rabbitmq and web stomp setup - mavenea/mavencrm GitHub Wiki

let's get the dokku plugin for rabbitmq

# on 0.19.x+
sudo dokku plugin:install https://github.com/dokku/dokku-rabbitmq.git rabbitmq

we need to use a custom docker image. the custom Dockerfile enables stomp and webstomp plugins. use docker build to build the image then

docker build -t mavencrm/rabbitmq-stomp:3.8-management https://github.com/mavenea/dokku-rabbitmq.git
dokku rabbitmq:create lolipop -i mavencrm/rabbitmq-stomp -I 3.8-management
dokku rabbitmq:link rabbitmq $APP

create user for stomp

# enter rabbitmq and 

rabbitmqctl add_user "userforstomp"
Adding user "userforstomp" ...
Password:
or 
rabbitmqctl add_user 'username' 'longpasswordhere'    
# 
rabbitmqctl list_vhosts --silent
# https://www.rabbitmq.com/access-control.html
rabbitmqctl set_permissions -p "virtualhost-name-here" "userforstomp" "permissions_here"
#permissions can be ".*" ".*" ".*"
Setting permissions for user "stomp" in vhost "virtualhost-name-here" ...

permissions should be restricted to the vhost and least permissions required. we need to update VTEProperties.php with rabbitmq and stomp configuration details - host/user/password/vhost/etc. we need to then update VTEProperties.php with username and password for both rabbitmq service (user/pass created automatically during install of service) and stomp (as defined above) - those passwords will automatically be encrypted by VTEProperties.php.

setting up nginx.conf.sigil

using a variable such as RABBITMQ_WS_IP with the command to retrieve the internal ip this is used as the proxy_pass url for the /stomp location. this way the ip address is obtained dynamically. another solution would be using a block such as

set_by_lua_block $rabbitmq_ip { return os.execute("dokku rabbitmq:info <rabbitmq service name> --internal-ip") }

this block added under the /stomp location will retrieve the ip address and store it in the var, then we can use the var as proxy_pass url.

the other option which is used in our confiruation is using a dokku env variable

# set the var RABBITMQ_WS_IP
dokku config:set mavencrm RABBITMQ_WS_IP=$(dokku rabbitmq:info <rabbitmq servicename> --internal-ip)
# nginx.conf.sigil will then use the variable
{{ var "RABBITMQ_WS_IP" }}

Note: this need to be run on restart of the machine or change of rabbitmq containers.

NGINX as Reverse Proxy to RabbitMQ WebStomp Server

NGINX can be easily configured as a reverse WebSocket proxy since version 1.3. WebSocket handshake is compatible with HTTP using Upgrade and Connection headers. As WebSocket connections are long running, NGINX will keep these connections open rather then closing them as idle.

RabbitMQ WebSocket server and Nginx

RabbitMQ WebStomp plugin uses cowboy http / websocket server behind the scene. It no longer uses SockJS-Server. This means it supports WebSocket connections only which is now supported by most recent browsers.

Set Upgrade and Connection headers explicitly for NGINX to handle a WebSocket connection.

location /stomp {
    proxy_pass http://app;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

Additionaly, such WebSocket proxy mechanism can be extended to have multiple backend servers for high availability and performance wth NGINX server acting as a load balancer between them.

By default NGINX closes the connection if no data is sent for 30 seconds. This timeout value can be changed wth proxy_read_timeout; alternatively, a WebSocket server should send ping messages periodically to reset the timer

https://www.rabbitmq.com/web-stomp.html

WebSocket traffic compression is enabled by default web_stomp.ws_opts.compress = true

WebSocket connection inactivity timeout web_stomp.ws_opts.idle_timeout = 60000 60 seconds by default

web_stomp.ws_opts.max_frame_size = 50000

check RabbitMQ docs