1"use strict";(self.webpackChunkrabbitmq_website=self.webpackChunkrabbitmq_website||[]).push([["15340"],{90183(e,n,s){s.r(n),s.d(n,{metadata:()=>i,default:()=>d,frontMatter:()=>r,contentTitle:()=>l,toc:()=>c,assets:()=>a});var i=JSON.parse('{"id":"web-stomp","title":"RabbitMQ Web STOMP Plugin","description":"\x3c!--","source":"@site/versioned_docs/version-4.3/web-stomp.md","sourceDirName":".","slug":"/web-stomp","permalink":"/docs/web-stomp","draft":false,"unlisted":false,"editUrl":"https://github.com/rabbitmq/rabbitmq-website/tree/main/versioned_docs/version-4.3/web-stomp.md","tags":[],"version":"4.3","frontMatter":{"title":"RabbitMQ Web STOMP Plugin"},"sidebar":"docsSidebar","previous":{"title":"STOMP Plugin","permalink":"/docs/stomp"},"next":{"title":"MQTT Plugin","permalink":"/docs/mqtt"}}'),t=s(74848),o=s(28453);let r={title:"RabbitMQ Web STOMP Plugin"},l="RabbitMQ Web STOMP Plugin",a={},c=[{value:"Overview",id:"overview",level:2},{value:"How It Works",id:"how-it-works",level:2},{value:"Enabling the Plugin",id:"enabling",level:2},{value:"Usage",id:"usage",level:2},{value:"Web STOMP Examples",id:"examples",level:2},{value:"Configuration",id:"configuration",level:2},{value:"TLS (WSS)",id:"tls",level:3},{value:"Enabled TLS Versions and Cipher Suites",id:"tls-versions",level:4},{value:"Troubleshooting TLS (WSS)",id:"troubleshooting-tls-wss",level:4},{value:"Basic HTTP Authentication",id:"http-auth",level:3},{value:"Proxy Protocol",id:"proxy-protocol",level:3},{value:"Advanced Options",id:"advanced-options",level:2},{value:"Content Encoding",id:"content-encoding",level:3},{value:"HTTP Options",id:"http-options",level:3},{value:"WebSocket Options",id:"websocket-options",level:3}];function h(e){let n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"rabbitmq-web-stomp-plugin",children:"RabbitMQ Web STOMP Plugin"})}),"\n",(0,t.jsx)(n.h2,{id:"overview",children:"Overview"}),"\n",(0,t.jsxs)(n.p,{children:["The Web STOMP plugin makes it possible to use\n",(0,t.jsx)(n.a,{href:"./stomp",children:"STOMP"})," over a WebSocket connection."]}),"\n",(0,t.jsx)(n.p,{children:"The goal of this plugin is to enable STOMP messaging in Web applications."}),"\n",(0,t.jsxs)(n.p,{children:["A similar plugin, ",(0,t.jsx)(n.a,{href:"./web-mqtt",children:"Web MQTT plugin"}),", makes it possible to use ",(0,t.jsx)(n.a,{href:"./mqtt",children:"MQTT"})," over\nWebSockets."]}),"\n",(0,t.jsx)(n.h2,{id:"how-it-works",children:"How It Works"}),"\n",(0,t.jsxs)(n.p,{children:['RabbitMQ Web STOMP plugin is a minimalistic "bridge" between the STOMP protocol implementation\nprovided by ',(0,t.jsx)(n.a,{href:"./stomp",children:"RabbitMQ STOMP plugin"}),", and WebSocket clients."]}),"\n",(0,t.jsxs)(n.p,{children:["RabbitMQ Web STOMP is fully compatible with the ",(0,t.jsx)(n.a,{href:"./stomp",children:"RabbitMQ STOMP"})," plugin."]}),"\n",(0,t.jsx)(n.h2,{id:"enabling",children:"Enabling the Plugin"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"rabbitmq_web_stomp"})," plugin ships with RabbitMQ."]}),"\n",(0,t.jsxs)(n.p,{children:["To enable the plugin run ",(0,t.jsx)(n.a,{href:"./man/rabbitmq-plugins.8",children:"rabbitmq-plugins"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rabbitmq-plugins enable rabbitmq_web_stomp\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsxs)(n.p,{children:["In order to use STOMP in a Web browser context, a JavaScript STOMP\nlibrary is required. We've tested a\n",(0,t.jsx)(n.a,{href:"https://github.com/jmesnil/stomp-websocket/",children:"stomp-websocket"})," library\nby ",(0,t.jsx)(n.a,{href:"https://github.com/jmesnil",children:"Jeff Mesnil"})," and\n",(0,t.jsx)(n.a,{href:"https://github.com/progrium",children:"Jeff Lindsay"}),".\n",(0,t.jsx)(n.a,{href:"https://github.com/rabbitmq/rabbitmq-server/blob/main/deps/rabbitmq_web_stomp_examples/priv/stomp.js",children:"This library"}),"\nis included as part of ",(0,t.jsx)(n.a,{href:"https://github.com/rabbitmq/rabbitmq-server/tree/main/deps/rabbitmq_web_stomp_examples",children:"RabbitMQ Web STOMP examples"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The WebSocket endpoint is available on the ",(0,t.jsx)(n.code,{children:"/ws"})," path:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"ws://127.0.0.1:15674/ws\n"})}),"\n",(0,t.jsx)(n.p,{children:"This endpoint will only work with Websocket capable clients. Note that\nsome configuration is necessary in order to accept binary messages."}),"\n",(0,t.jsx)(n.p,{children:"In order to establish connection from the browser using WebSocket\nyou may use co
1de like:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-html",children:'\x3c!-- include the client library --\x3e\n<script src="stomp.js"><\/script>\n'})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"<script>\nvar ws = new WebSocket('ws://127.0.0.1:15674/ws');\nvar client = Stomp.over(ws);\n// ...\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Once you have the ",(0,t.jsx)(n.code,{children:"client"})," object you can follow API's exposed by\nstomp.js library. The next step is usually to establish a STOMP\nconnection with the broker:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"// ...\nvar on_connect = function() {\n console.log('connected');\n};\nvar on_error = function() {\n console.log('error');\n};\nclient.connect('guest', 'guest', on_connect, on_error, '/');\n// ...\n"})}),"\n",(0,t.jsx)(n.h2,{id:"examples",children:"Web STOMP Examples"}),"\n",(0,t.jsxs)(n.p,{children:["A few simple Web STOMP examples are provided as a\n",(0,t.jsx)(n.a,{href:"https://github.com/rabbitmq/rabbitmq-server/tree/main/deps/rabbitmq_web_stomp_examples",children:"RabbitMQ Web STOMP examples"}),"\nplugin. To get it running follow the installation instructions for that plugin\nand enable the plugin:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rabbitmq-plugins enable rabbitmq_web_stomp_examples\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The examples will be available under\n",(0,t.jsx)(n.a,{href:"http://127.0.0.1:15670/",children:"http://127.0.0.1:15670/"})," url. You will see two examples:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'"echo" - shows how to use STOMP to do simple message broadcasting'}),"\n",(0,t.jsx)(n.li,{children:'"bunny" - example of a simple collaboration canvas painting app'}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["We encourage you to take a look ",(0,t.jsx)(n.a,{href:"https://github.com/rabbitmq/rabbitmq-server/tree/main/deps/rabbitmq_web_stomp_examples/priv",children:"at the source code"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"configuration",children:"Configuration"}),"\n",(0,t.jsxs)(n.p,{children:["When no configuration is specified the Web STOMP plugin will listen on\nall interfaces on port 15674 and have a default user login/passcode of\n",(0,t.jsx)(n.code,{children:"guest"}),"/",(0,t.jsx)(n.code,{children:"guest"}),". Note that this user is only ",(0,t.jsx)(n.a,{href:"./access-control#loopback-users",children:"allowed to connect from localhost"})," by default.\nWe highly recommend creating a separate user for production systems."]}),"\n",(0,t.jsxs)(n.p,{children:["To change the listener port, edit your\n",(0,t.jsx)(n.a,{href:"./configure#configuration-files",children:"Advanced configuration file"}),",\nto contain a ",(0,t.jsx)(n.code,{children:"tcp_config"})," section with a ",(0,t.jsx)(n.code,{children:"port"})," variable for the ",(0,t.jsx)(n.code,{children:"rabbitmq_web_stomp"})," application."]}),"\n",(0,t.jsx)(n.p,{children:"For example, a complete configuration file which changes the listener\nport to 12345 would look like:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",children:"web_stomp.tcp.port = 12345\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can use the ",(0,t.jsx)(n.code,{children:"tcp_config"})," section to specify any TCP option you need.\nSee the ",(0,t.jsx)(n.a,{href:"./networking",children:"RabbitMQ Networking guide"})," and ",(0,t.jsx)(n.a,{href:"https://ninenines.eu/docs/en/ranch/2.1/guide/",children:"Ranch documentation"}),"\nfor details about accepted parameters."]}),"\n",(0,t.jsx)(n.h3,{id:"tls",children:"TLS (WSS)"}),"\n",(0,t.jsxs)(n.p,{children:["The plugin supports WebSockets with TLS (WSS) connections. See ",(0,t.jsx)(n.a,{href:"./ssl",children:"TLS guide"}),"\nto learn more about TLS support in RabbitMQ."]}),"\n",(0,t.jsxs)(n.p,{children:["TLS configuration parameters are provided in the ",(0,t.jsx)(n.code,{children:"web_stomp.ssl"})," section:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",children:"web_stomp.ssl.port = 15673\nweb_stomp.ssl.backlog = 1024\nweb_stomp.ssl.cacertfile = /path/to/ca_certificate.pem\nweb_stomp.ssl.certfile = /path/to/server_certificate.pem\nweb_stomp.ssl.keyfile = /path/to/server_key.pem\nweb_stomp.ssl.password = changeme\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The TLS listener port, server certificate file, private key and CA certificate bundle are mandatory options.\nPassword is also mandatory if the private key uses one.\nAn extended list of TLS settings is largely identical to those ",(0,t.jsx)(n.a,{href:"./ssl",children:"for the core server"}),".\nFull list of options accepted by this plugin can be found in ",(0,t.jsx)(n.a,{href:"https://ninenines.eu/docs/en/ranch/1.7/manual/ranch_ssl/",children:"Ranch documentation"}),"."]}),"\n",(0,t.jsx)(n.h4,{id:"tls-versions",children:"Enabled TLS Versions and Cipher Suites"}),"\n",(0,t.jsx)(n.p,{children:"It is possible to configure what TLS versions and cipher suites will be used by RabbitMQ. Note that not all\nsuites will be available on all systems."}),"\n",(0,t.jsxs)(n.p,{children:["RabbitMQ TLS guide has ",(0,t.jsx)(n.a,{href:"./ssl#tls-versions",children:"a section on TLS versions"})," and another one\n",(0,t.jsx)(n.a,{href:"./ssl#cipher-suites",children:"on cipher suites"}),". Below is an example\nin the ",(0,t.jsx)(n.a,{href:"./configure#advanced-config-file",children:"advanced config format"}
1)," that configures cipher suites\nand a number of other ",(0,t.jsx)(n.a,{href:"./ssl",children:"TLS options"})," for the plugin:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",children:"web_stomp.ssl.port = 15673\nweb_stomp.ssl.backlog = 1024\nweb_stomp.ssl.certfile = /path/to/server_certificate.pem\nweb_stomp.ssl.keyfile = /path/to/server_key.pem\nweb_stomp.ssl.cacertfile = /path/to/ca_certificate_bundle.pem\nweb_stomp.ssl.password = changeme\n\nweb_stomp.ssl.honor_cipher_order = true\nweb_stomp.ssl.honor_ecc_order = true\nweb_stomp.ssl.client_renegotiation = false\nweb_stomp.ssl.secure_renegotiate = true\n\nweb_stomp.ssl.versions.1 = tlsv1.2\nweb_stomp.ssl.versions.2 = tlsv1.1\nweb_stomp.ssl.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384\nweb_stomp.ssl.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384\nweb_stomp.ssl.ciphers.3 = ECDHE-ECDSA-AES256-SHA384\nweb_stomp.ssl.ciphers.4 = ECDHE-RSA-AES256-SHA384\nweb_stomp.ssl.ciphers.5 = ECDH-ECDSA-AES256-GCM-SHA384\nweb_stomp.ssl.ciphers.6 = ECDH-RSA-AES256-GCM-SHA384\nweb_stomp.ssl.ciphers.7 = ECDH-ECDSA-AES256-SHA384\nweb_stomp.ssl.ciphers.8 = ECDH-RSA-AES256-SHA384\nweb_stomp.ssl.ciphers.9 = DHE-RSA-AES256-GCM-SHA384\n"})}),"\n",(0,t.jsx)(n.h4,{id:"troubleshooting-tls-wss",children:"Troubleshooting TLS (WSS)"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"./ssl",children:"RabbitMQ TLS"})," and ",(0,t.jsx)(n.a,{href:"./troubleshooting-ssl",children:"TLS Troubleshooting"})," for additional\ninformation."]}),"\n",(0,t.jsx)(n.h3,{id:"http-auth",children:"Basic HTTP Authentication"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"use_http_auth"})," option extends the authentication by\nallowing clients to send the login and passcode in the\nHTTP authorisation header (using HTTP Basic Auth). If\npresent, these credentials will be used. Otherwise, the\ndefault STOMP credentials are used. The credentials found\nin the CONNECT frame, if any, are ignored."]}),"\n",(0,t.jsxs)(n.p,{children:["This is an advanced feature that is only exposed via the ",(0,t.jsx)(n.a,{href:"./configure#configuration-files",children:"advanced configuration file"}),"\nor the ",(0,t.jsx)("a",{href:"./configure#erlang-term-config-file",children:"classic config format"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-erlang",children:"[\n {rabbitmq_web_stomp,\n [{use_http_auth, true}]}\n].\n"})}),"\n",(0,t.jsx)(n.h3,{id:"proxy-protocol",children:"Proxy Protocol"}),"\n",(0,t.jsxs)(n.p,{children:["The Web STOMP plugin supports the ",(0,t.jsx)(n.a,{href:"http://www.haproxy.org/download/3.1/doc/proxy-protocol.txt",children:"proxy protocol"}),".\nThis feature is deactivated by default, to activate it for clients:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",children:"web_stomp.proxy_protocol = true\n"})}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"./networking#proxy-protocol",children:"Networking Guide"})," for more information\nabout the proxy protocol."]}),"\n",(0,t.jsx)(n.h2,{id:"advanced-options",children:"Advanced Options"}),"\n",(0,t.jsxs)(n.p,{children:["The Web STOMP plugin uses the Cowboy HTTP and WebSocket server under the hood. Cowboy\nprovides ",(0,t.jsx)(n.a,{href:"https://ninenines.eu/docs/en/cowboy/2.10/manual/cowboy_http/",children:"a number of options"}),"\nthat can be used to customize the behavior of the server\nw.r.t. WebSocket connection handling."]}),"\n",(0,t.jsx)(n.p,{children:"Some settings are generic HTTP ones, others are specific to WebSockets."}),"\n",(0,t.jsx)(n.h3,{id:"content-encoding",children:"Content Encoding"}),"\n",(0,t.jsxs)(n.p,{children:["By default, the Web STOMP plugin will expect to handle messages\nencoded as UTF-8. The WebSocket endpoint exposed by this plugin can be switched to binary mode if needed\nusing the ",(0,t.jsx)(n.code,{children:"ws_frame"})," option:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",children:"web_stomp.ws_frame = binary\n"})}),"\n",(0,t.jsx)(n.h3,{id:"http-options",children:"HTTP Options"}),"\n",(0,t.jsxs)(n.p,{children:["Generic HTTP server settings can be specified using ",(0,t.jsx)(n.code,{children:"web_stomp.cowboy_opts.*"})," keys,\nfor example:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",children:"# connection inactivity timeout\nweb_stomp.cowboy_opts.idle_timeout = 60000\n# max number of pending requests allowed on a connection\nweb_stomp.cowboy_opts.max_keepalive = 200\n# max number of headers in a request\nweb_stomp.cowboy_opts.max_headers = 100\n# max number of empty lines before request body\nweb_stomp.cowboy_opts.max_empty_lines = 5\n# max request line length allowed in requests\nweb_stomp.cowboy_opts.max_request_line_length\n"})}),"\n",(0,t.jsx)(n.h3,{id:"websocket-options",children:"WebSocket Options"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-ini",children:"# WebSocket traffic compression is enabled by default\nweb_stomp.ws_opts.compress = true\n\n# WebSocket connection inactivity timeout\nweb_stomp.ws_opts.idle_timeout = 60000\n\nweb_stomp.ws_opts.max_frame_size = 50000\n"})})]})}function d(e={}){let{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453(e,n,s){s.d(n,{R:()=>r,x:()=>l});var i=s(96540);let t={},o=i.createContext(t);function r(e){let n=i.useContext(o);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.