Awesome
websocket-as-promised
<img alt="websocket-as-promised logo" align="right" src="https://user-images.githubusercontent.com/1473072/32486445-b2443538-c3b7-11e7-8e9f-94c95efad760.png"/>A WebSocket client library with Promise-based API for browser and Node.js.
Example
import WebSocketAsPromised from 'websocket-as-promised';
// create instance of WebSocket connection
const wsp = new WebSocketAsPromised('ws://example.com');
// wait for WebSocket connection to open
await wsp.open();
// send some data
wsp.send('data');
// wait for connection to close
await wsp.close();
Contents
Requirements
- global
Promise
constructor
Installation
npm i websocket-as-promised --save
Usage in browser
import WebSocketAsPromised from 'websocket-as-promised';
const wsp = new WebSocketAsPromised('ws://example.com');
wsp.open()
.then(() => wsp.send('message'))
.then(() => wsp.close())
.catch(e => console.error(e));
Or with ES7 async / await:
import WebSocketAsPromised from 'websocket-as-promised';
const wsp = new WebSocketAsPromised('ws://example.com');
(async () => {
try {
await wsp.open();
wsp.send('message');
} catch(e) {
console.error(e);
} finally {
await wsp.close();
}
})();
Usage in Node.js
As there is no built-in WebSocket client in Node.js, you should use a third-party WebSocket npm package.
Usage with websocket
Here you should use W3C compatible client - W3CWebSocket:
const WebSocketAsPromised = require('websocket-as-promised');
const W3CWebSocket = require('websocket').w3cwebsocket;
const wsp = new WebSocketAsPromised('ws://example.com', {
createWebSocket: url => new W3CWebSocket(url)
});
wsp.open()
.then(() => wsp.send('message'))
.then(() => wsp.close())
.catch(e => console.error(e));
Usage with ws
Here it is important to define extractMessageData
option as event data are passed directly to onmessage
handler,
not as event.data
by spec:
const WebSocketAsPromised = require('websocket-as-promised');
const WebSocket = require('ws');
const wsp = new WebSocketAsPromised('ws://example.com', {
createWebSocket: url => new WebSocket(url),
extractMessageData: event => event, // <- this is important
});
wsp.open()
.then(() => wsp.send('message'))
.then(() => wsp.close())
.catch(e => console.error(e));
Sending raw data
To send raw data use .send()
method:
wsp.send('foo');
To handle raw data from server use .onMessage
channel:
wsp.onMessage.addListener(data => console.log(data));
Sending JSON
To send JSON you should define packMessage / unpackMessage
options:
const wsp = new WebSocketAsPromised(wsUrl, {
packMessage: data => JSON.stringify(data),
unpackMessage: data => JSON.parse(data)
});
To send data use .sendPacked()
method passing json as parameter:
wsp.sendPacked({foo: 'bar'});
To read unpacked data from received message you can subscribe to onUnpackedMessage
channel:
wsp.onUnpackedMessage.addListener(data => console.log(data.status));
Sending binary
Example of sending Uint8Array
:
const wsp = new WebSocketAsPromised(wsUrl, {
packMessage: data => (new Uint8Array(data)).buffer,
unpackMessage: data => new Uint8Array(data),
});
wsp.open()
.then(() => wsp.sendPacked([1, 2, 3]))
.then(() => wsp.close())
.catch(e => console.error(e));
Sending requests
websocket-as-promised provides simple request-response mechanism (JSON RPC).
Method .sendRequest()
sends message with unique requestId
and returns promise.
That promise get resolved when response message with the same requestId
comes.
For reading/setting requestId
from/to message there are two functions defined in options attachRequestId / extractRequestId
:
const wsp = new WebSocketAsPromised(wsUrl, {
packMessage: data => JSON.stringify(data),
unpackMessage: data => JSON.parse(data),
attachRequestId: (data, requestId) => Object.assign({id: requestId}, data), // attach requestId to message as `id` field
extractRequestId: data => data && data.id, // read requestId from message `id` field
});
wsp.open()
.then(() => wsp.sendRequest({foo: 'bar'})) // actually sends {foo: 'bar', id: 'xxx'}, because `attachRequestId` defined above
.then(response => console.log(response)); // waits server message with corresponding requestId: {id: 'xxx', ...}
By default requestId
value is auto-generated, but you can set it manually:
wsp.sendRequest({foo: 'bar'}, {requestId: 42});
Note: you should implement yourself attaching
requestId
on server side.
API
Classes
<dl> <dt><a href="#WebSocketAsPromised">WebSocketAsPromised</a></dt> <dd></dd> </dl>Typedefs
<dl> <dt><a href="#Options">Options</a> : <code>Object</code></dt> <dd></dd> </dl><a name="WebSocketAsPromised"></a>
WebSocketAsPromised
Kind: global class
- WebSocketAsPromised
- new WebSocketAsPromised(url, [options])
- .ws ⇒ <code>WebSocket</code>
- .url ⇒ <code>String</code>
- .isOpening ⇒ <code>Boolean</code>
- .isOpened ⇒ <code>Boolean</code>
- .isClosing ⇒ <code>Boolean</code>
- .isClosed ⇒ <code>Boolean</code>
- .onOpen ⇒ <code>Channel</code>
- .onSend ⇒ <code>Channel</code>
- .onMessage ⇒ <code>Channel</code>
- .onUnpackedMessage ⇒ <code>Channel</code>
- .onResponse ⇒ <code>Channel</code>
- .onClose ⇒ <code>Channel</code>
- .onError ⇒ <code>Channel</code>
- .open() ⇒ <code>Promise.<Event></code>
- .sendRequest(data, [options]) ⇒ <code>Promise</code>
- .sendPacked(data)
- .send(data)
- .waitUnpackedMessage(predicate, [options]) ⇒ <code>Promise</code>
- .close([code], [reason]) ⇒ <code>Promise.<Event></code>
- .removeAllListeners()
<a name="new_WebSocketAsPromised_new"></a>
new WebSocketAsPromised(url, [options])
Constructor. Unlike original WebSocket it does not immediately open connection.
Please call open()
method to connect.
Param | Type | Description |
---|---|---|
url | <code>String</code> | WebSocket URL |
[options] | <code>Options</code> |
<a name="WebSocketAsPromised+ws"></a>
wsp.ws ⇒ <code>WebSocket</code>
Returns original WebSocket instance created by options.createWebSocket
.
Kind: instance property of <code>WebSocketAsPromised</code>
<a name="WebSocketAsPromised+url"></a>
wsp.url ⇒ <code>String</code>
Returns WebSocket url.
Kind: instance property of <code>WebSocketAsPromised</code>
<a name="WebSocketAsPromised+isOpening"></a>
wsp.isOpening ⇒ <code>Boolean</code>
Is WebSocket connection in opening state.
Kind: instance property of <code>WebSocketAsPromised</code>
<a name="WebSocketAsPromised+isOpened"></a>
wsp.isOpened ⇒ <code>Boolean</code>
Is WebSocket connection opened.
Kind: instance property of <code>WebSocketAsPromised</code>
<a name="WebSocketAsPromised+isClosing"></a>
wsp.isClosing ⇒ <code>Boolean</code>
Is WebSocket connection in closing state.
Kind: instance property of <code>WebSocketAsPromised</code>
<a name="WebSocketAsPromised+isClosed"></a>
wsp.isClosed ⇒ <code>Boolean</code>
Is WebSocket connection closed.
Kind: instance property of <code>WebSocketAsPromised</code>
<a name="WebSocketAsPromised+onOpen"></a>
wsp.onOpen ⇒ <code>Channel</code>
Event channel triggered when connection is opened.
Kind: instance property of <code>WebSocketAsPromised</code>
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onOpen.addListener(() => console.log('Connection opened'));
<a name="WebSocketAsPromised+onSend"></a>
wsp.onSend ⇒ <code>Channel</code>
Event channel triggered every time when message is sent to server.
Kind: instance property of <code>WebSocketAsPromised</code>
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onSend.addListener(data => console.log('Message sent', data));
<a name="WebSocketAsPromised+onMessage"></a>
wsp.onMessage ⇒ <code>Channel</code>
Event channel triggered every time when message received from server.
Kind: instance property of <code>WebSocketAsPromised</code>
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onMessage.addListener(message => console.log(message));
<a name="WebSocketAsPromised+onUnpackedMessage"></a>
wsp.onUnpackedMessage ⇒ <code>Channel</code>
Event channel triggered every time when received message is successfully unpacked. For example, if you are using JSON transport, the listener will receive already JSON parsed data.
Kind: instance property of <code>WebSocketAsPromised</code>
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onUnpackedMessage.addListener(data => console.log(data.foo));
<a name="WebSocketAsPromised+onResponse"></a>
wsp.onResponse ⇒ <code>Channel</code>
Event channel triggered every time when response to some request comes. Received message considered a response if requestId is found in it.
Kind: instance property of <code>WebSocketAsPromised</code>
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onResponse.addListener(data => console.log(data));
<a name="WebSocketAsPromised+onClose"></a>
wsp.onClose ⇒ <code>Channel</code>
Event channel triggered when connection closed.
Listener accepts single argument {code, reason}
.
Kind: instance property of <code>WebSocketAsPromised</code>
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onClose.addListener(event => console.log(`Connections closed: ${event.reason}`));
<a name="WebSocketAsPromised+onError"></a>
wsp.onError ⇒ <code>Channel</code>
Event channel triggered when by Websocket 'error' event.
Kind: instance property of <code>WebSocketAsPromised</code>
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onError.addListener(event => console.error(event));
<a name="WebSocketAsPromised+open"></a>
wsp.open() ⇒ <code>Promise.<Event></code>
Opens WebSocket connection. If connection already opened, promise will be resolved with "open event".
Kind: instance method of <code>WebSocketAsPromised</code>
<a name="WebSocketAsPromised+sendRequest"></a>
wsp.sendRequest(data, [options]) ⇒ <code>Promise</code>
Performs request and waits for response.
Kind: instance method of <code>WebSocketAsPromised</code>
Param | Type | Default |
---|---|---|
data | <code>*</code> | |
[options] | <code>Object</code> | |
[options.requestId] | <code>String</code> | <code>Number</code> | <code><auto-generated></code> |
[options.timeout] | <code>Number</code> | <code>0</code> |
<a name="WebSocketAsPromised+sendPacked"></a>
wsp.sendPacked(data)
Packs data with options.packMessage
and sends to the server.
Kind: instance method of <code>WebSocketAsPromised</code>
Param | Type |
---|---|
data | <code>*</code> |
<a name="WebSocketAsPromised+send"></a>
wsp.send(data)
Sends data without packing.
Kind: instance method of <code>WebSocketAsPromised</code>
Param | Type |
---|---|
data | <code>String</code> | <code>Blob</code> | <code>ArrayBuffer</code> |
<a name="WebSocketAsPromised+waitUnpackedMessage"></a>
wsp.waitUnpackedMessage(predicate, [options]) ⇒ <code>Promise</code>
Waits for particular message to come.
Kind: instance method of <code>WebSocketAsPromised</code>
Param | Type | Default | Description |
---|---|---|---|
predicate | <code>function</code> | function to check incoming message. | |
[options] | <code>Object</code> | ||
[options.timeout] | <code>Number</code> | <code>0</code> | |
[options.timeoutError] | <code>Error</code> |
Example
const response = await wsp.waitUnpackedMessage(data => data && data.foo === 'bar');
<a name="WebSocketAsPromised+close"></a>
wsp.close([code], [reason]) ⇒ <code>Promise.<Event></code>
Closes WebSocket connection. If connection already closed, promise will be resolved with "close event".
Kind: instance method of <code>WebSocketAsPromised</code>
Param | Type | Default | Description |
---|---|---|---|
[code] | <code>number</code> | <code>1000</code> | A numeric value indicating the status code. |
[reason] | <code>string</code> | A human-readable reason for closing connection. |
<a name="WebSocketAsPromised+removeAllListeners"></a>
wsp.removeAllListeners()
Removes all listeners from WSP instance. Useful for cleanup.
Kind: instance method of <code>WebSocketAsPromised</code>
<a name="Options"></a>
Options : <code>Object</code>
Kind: global typedef
Defaults: please see options.js
Properties
Name | Type | Default | Description |
---|---|---|---|
[createWebSocket] | <code>function</code> | <code>url => new WebSocket(url)</code> | custom function for WebSocket construction. |
[packMessage] | <code>function</code> | <code>noop</code> | packs message for sending. For example, data => JSON.stringify(data) . |
[unpackMessage] | <code>function</code> | <code>noop</code> | unpacks received message. For example, data => JSON.parse(data) . |
[attachRequestId] | <code>function</code> | <code>noop</code> | injects request id into data. For example, (data, requestId) => Object.assign({requestId}, data) . |
[extractRequestId] | <code>function</code> | <code>noop</code> | extracts request id from received data. For example, data => data.requestId . |
[extractMessageData] | <code>function</code> | <code>event => event.data</code> | extracts data from event object. |
timeout | <code>Number</code> | <code>0</code> | timeout for opening connection and sending messages. |
connectionTimeout | <code>Number</code> | <code>0</code> | special timeout for opening connection, by default equals to timeout . |
Changelog
Please see CHANGELOG.md.
License
MIT @ Vitaliy Potapov
<div align="center"> * * *<br> <i>If you love :heart: JavaScript and would like to track new trending repositories, <br> have a look on <a href="https://github.com/vitalets/github-trending-repos">vitalets/github-trending-repos</a>.</i> </div>