# webstomp-client This library provides a [stomp](https://stomp.github.io/) client for Web browsers and nodejs through Web Sockets. ## Project Status This is a fork of the original [stomp-websocket](https://github.com/jmesnil/stomp-websocket) re-written in ES6 and incorporate pending pull requests. All credits goes to the original authors: Jeff Mesnil & Jeff Lindsay. ## Browsers support Only ES5 compatible modern browsers are supported. If you need a websocket polyfill you can use [sockjs](http://sockjs.org) ## nodejs support As nodejs does not have a WebSocket object like browsers have, you must choose a websocket client and use [webstomp.over](https://github.com/JSteunou/webstomp-client#overws-options) instead of `webstomp.client`. Choosing a good client is maybe the most difficult part: * [websocket](https://www.npmjs.com/package/websocket) * [ws](https://www.npmjs.com/package/ws) * [sockjs](https://www.npmjs.com/package/sockjs-client) If your server part is also SockJS * ... add yours ## Example `npm run example` will open examples in browser and try to connect to [RabbitMQ Web-Stomp](https://www.rabbitmq.com/web-stomp.html) default Web Sockets url. `node run example/broadcast-node.js` will run a dead simple nodejs example. ## Use `npm install webstomp-client` ### Web browser old fashion style ```html ``` `webstomp` will be a global variable. ### CommonJS ```js var webstomp = require('webstomp-client'); ``` ### ES6 modules ``` import webstomp from 'webstomp-client'; ``` By default it will load `dist/webstomp.js`, but the npm package.json es6 entry point to the es6 src file if you prefer loading this version. ## API Jeff Mesnil stomp-websocket [documentation](http://jmesnil.net/stomp-websocket/doc/) is still a must read even if the API [evolved](CHANGELOG.md) a little ### webstomp #### client(url, [options]) Uses global `WebSocket` object for you to return a webstomp `Client` object. ##### url Web Sockets endpoint url ##### options * protocols: default to `['v10.stomp', 'v11.stomp', 'v12.stomp']` * binary: default to `false`. See [binary](#binary) section. * heartbeat: default to `{incoming: 10000, outgoing: 10000}`. You can provide `false` to cut it (recommended when the server is a SockJS server) or a definition object. * debug: default to `true`. Will log frame using `console.log` #### over(ws, [options]) Takes a `WebSocket` alike object **instance** to return a webstomp `Client` object. Allows you to use another `WebSocket` object than the default one. 2 cases for this: * you do not want `webstomp.client` to create a default instance for you. * you are in an old browser or nodejs and do not have a global `WebSocket` object that `webstomp.client` can use. ##### ws `WebSocket` object instance ##### options * binary: default to `false`. See [binary](#binary) section. * heartbeat: default to `{incoming: 10000, outgoing: 10000}`. You can provide `false` to cut it (recommended when the server is a SockJS server) or a definition object. * debug: default to `true`. Will log frame using `console.log` ### VERSIONS #### supportedVersions() List all STOMP specifications supported. #### supportedProtocols() List all websocket STOMP protocols supported. Useful when creating your own `WebSocket` instance, although optional, protocols is often the second parameter. ### Client A client instance can and should be created through `webstomp.client` or `webstomp.over` #### connect * `connect(headers, connectCallback)` * `connect(headers, connectCallback, errorCallback)` * `connect(login, passcode, connectCallback)` * `connect(login, passcode, connectCallback, errorCallback)` * `connect(login, passcode, connectCallback, errorCallback, host)` #### disconnect(disconnectCallback, headers={}) #### send(destination, body='', headers={}) #### subscribe(destination, callback, headers={}) #### unsubscribe(id, header={}) It is preferable to unsubscribe from a subscription by calling `unsubscribe()` directly on the object returned by `client.subscribe()` ```js var subscription = client.subscribe(destination, onmessage); ... subscription.unsubscribe(headers); ``` `headers` are optionals #### onreceive(frame) If defined on the client instance this function will be called whenever a message is received and in the absence of an explicit `subscribe()`. Some brokers (at least RabbitMQ) will setup an internal routing topology for RPC patterns when a message is sent with certain headers. In RabbitMQ it's called [Direct Reply-To](https://www.rabbitmq.com/direct-reply-to.html) *On the client* ``` let onreceive(frame)=>{ console.log('Message received',frame) } client.onreceive=onreceive let headers = { 'reply-to' :'/temp-queue/webstomp', } client.send('/topic/public.echo.hi.mom','a message') ``` *On the server (using [Amqplib](http://www.squaremobius.net/amqp.node/channel_api.html#channel_publish) for example)* ``` ch.publish('',raw_message.properties.replyTo,Buffer.from('a reply')) ``` #### begin([transaction]) If no transaction ID is passed, one will be created automatically #### commit(transaction) It is preferable to commit a transaction by calling `commit()` directly on the object returned by `client.begin()`: ```js var tx = client.begin(txid); ... tx.commit(); ``` #### abort(transaction) It is preferable to abort a transaction by calling `abort()` directly on the object returned by `client.begin()`: ```js var tx = client.begin(txid); ... tx.abort(); ``` #### ack(messageID, subscription, headers={}) It is preferable to acknowledge a message by calling `ack()` directly on the message handled by a subscription callback: ```js client.subscribe(destination, (message) => { // process the message // acknowledge it message.ack(); }, {'ack': 'client'} ); ``` #### nack(messageID, subscription, headers={}) It is preferable to nack a message by calling `nack()` directly on the message handled by a subscription callback: ```js client.subscribe(destination, (message) => { // process the message // acknowledge it message.nack(); }, {'ack': 'client'} ); ``` #### debug Will use `console.log` by default. Override it to update its behavior. ## Binary It is possible to use binary frame instead of string frame over Web Sockets. * client side: set the binary option to true. * server side: use a compatible websocket server, like with [RabbitMQ Web-Stomp](https://www.rabbitmq.com/web-stomp.html) since 3.6 ## Heartbeat Not all server are compatible, you may have to deactivate this feature depending the server you are using. For example RabbitMQ Web-Stomp is compatible only since 3.6 with native Web Sockets server. ## Authors * [Jérôme Steunou](https://github.com/JSteunou) * [Jeff Mesnil](http://jmesnil.net/) * [Jeff Lindsay](http://github.com/progrium)