promised-websocket
v2.0.4
Published
A WebSocket client library providing Promise-based API for connecting, disconnecting and messaging with server. Original developed by Vitaliy Potapov([email protected]).
Downloads
18
Maintainers
Readme
Base on vitalets/websocket-as-promised
.
Introducing a onUnpackedNotif
event channel. Request/response messages both have an id
attribute, while notification
messages are messages that do not contain an id
attribute and can be used for server-initiated notification messages.
Note: The requestId property on the server side must be named
id
; otherwise, theonUnpackedNotif
event will be fired every time a message is received.
websocket-as-promised
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.
Listen notifications
When use send/request pattern, you can listen a notification which the message does not contain a id
property.
wsp.onUnpackedNotif.addListener(data => console.log(JSON.stringify(data)));
API
Classes
Typedefs
WebSocketAsPromised
Kind: global class
- WebSocketAsPromised
- new WebSocketAsPromised(url, [options])
- .ws ⇒ WebSocket
- .url ⇒ String
- .isOpening ⇒ Boolean
- .isOpened ⇒ Boolean
- .isClosing ⇒ Boolean
- .isClosed ⇒ Boolean
- .onOpen ⇒ Channel
- .onSend ⇒ Channel
- .onMessage ⇒ Channel
- .onUnpackedMessage ⇒ Channel
- .onUnpackedNotif ⇒ Channel
- .onResponse ⇒ Channel
- .onClose ⇒ Channel
- .onError ⇒ Channel
- .open() ⇒ Promise.<Event>
- .sendRequest(data, [options]) ⇒ Promise
- .sendPacked(data)
- .send(data)
- .waitUnpackedMessage(predicate, [options]) ⇒ Promise
- .close([code], [reason]) ⇒ Promise.<Event>
- .removeAllListeners()
new WebSocketAsPromised(url, [options])
Constructor. Unlike original WebSocket it does not immediately open connection.
Please call open()
method to connect.
| Param | Type | Description | | --- | --- | --- | | url | String | WebSocket URL | | [options] | Options | |
wsp.ws ⇒ WebSocket
Returns original WebSocket instance created by options.createWebSocket
.
Kind: instance property of WebSocketAsPromised
wsp.url ⇒ String
Returns WebSocket url.
Kind: instance property of WebSocketAsPromised
wsp.isOpening ⇒ Boolean
Is WebSocket connection in opening state.
Kind: instance property of WebSocketAsPromised
wsp.isOpened ⇒ Boolean
Is WebSocket connection opened.
Kind: instance property of WebSocketAsPromised
wsp.isClosing ⇒ Boolean
Is WebSocket connection in closing state.
Kind: instance property of WebSocketAsPromised
wsp.isClosed ⇒ Boolean
Is WebSocket connection closed.
Kind: instance property of WebSocketAsPromised
wsp.onOpen ⇒ Channel
Event channel triggered when connection is opened.
Kind: instance property of WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onOpen.addListener(() => console.log('Connection opened'));
wsp.onSend ⇒ Channel
Event channel triggered every time when message is sent to server.
Kind: instance property of WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onSend.addListener(data => console.log('Message sent', data));
wsp.onMessage ⇒ Channel
Event channel triggered every time when message received from server.
Kind: instance property of WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onMessage.addListener(message => console.log(message));
wsp.onUnpackedMessage ⇒ Channel
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 WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onUnpackedMessage.addListener(data => console.log(data.foo));
wsp.onUnpackedNotif ⇒ Channel
Event channel triggered every time when a notification which does not contain an id
property is successfully unpacked.
For example, if you are using JSON transport, the listener will receive already JSON parsed data.
Kind: instance property of WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onUnpackedNotif.addListener(data => console.log(data.foo));
wsp.onResponse ⇒ Channel
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 WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onResponse.addListener(data => console.log(data));
wsp.onClose ⇒ Channel
Event channel triggered when connection closed.
Listener accepts single argument {code, reason}
.
Kind: instance property of WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onClose.addListener(event => console.log(`Connections closed: ${event.reason}`));
wsp.onError ⇒ Channel
Event channel triggered when by Websocket 'error' event.
Kind: instance property of WebSocketAsPromised
See: https://vitalets.github.io/chnl/#channel
Example
wsp.onError.addListener(event => console.error(event));
wsp.open() ⇒ Promise.<Event>
Opens WebSocket connection. If connection already opened, promise will be resolved with "open event".
Kind: instance method of WebSocketAsPromised
wsp.sendRequest(data, [options]) ⇒ Promise
Performs request and waits for response.
Kind: instance method of WebSocketAsPromised
| Param | Type | Default | | --- | --- | --- | | data | * | | | [options] | Object | | | [options.requestId] | String | Number | <auto-generated> | | [options.timeout] | Number | 0 |
wsp.sendPacked(data)
Packs data with options.packMessage
and sends to the server.
Kind: instance method of WebSocketAsPromised
| Param | Type | | --- | --- | | data | * |
wsp.send(data)
Sends data without packing.
Kind: instance method of WebSocketAsPromised
| Param | Type | | --- | --- | | data | String | Blob | ArrayBuffer |
wsp.waitUnpackedMessage(predicate, [options]) ⇒ Promise
Waits for particular message to come.
Kind: instance method of WebSocketAsPromised
| Param | Type | Default | Description | | --- | --- | --- | --- | | predicate | function | | function to check incoming message. | | [options] | Object | | | | [options.timeout] | Number | 0 | | | [options.timeoutError] | Error | | |
Example
const response = await wsp.waitUnpackedMessage(data => data && data.foo === 'bar');
wsp.close([code], [reason]) ⇒ Promise.<Event>
Closes WebSocket connection. If connection already closed, promise will be resolved with "close event".
Kind: instance method of WebSocketAsPromised
| Param | Type | Default | Description | | --- | --- | --- | --- | | [code] | number | 1000 | A numeric value indicating the status code. | | [reason] | string | | A human-readable reason for closing connection. |
wsp.removeAllListeners()
Removes all listeners from WSP instance. Useful for cleanup.
Kind: instance method of WebSocketAsPromised
Options : Object
Kind: global typedef
Defaults: please see options.js
Properties
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| [createWebSocket] | function | url => new WebSocket(url) | custom function for WebSocket construction. |
| [packMessage] | function | noop | packs message for sending. For example, data => JSON.stringify(data)
. |
| [unpackMessage] | function | noop | unpacks received message. For example, data => JSON.parse(data)
. |
| [attachRequestId] | function | noop | injects request id into data. For example, (data, requestId) => Object.assign({requestId}, data)
. |
| [extractRequestId] | function | noop | extracts request id from received data. For example, data => data.requestId
. |
| [extractMessageData] | function | event => event.data | extracts data from event object. |
| timeout | Number | 0 | timeout for opening connection and sending messages. |
| connectionTimeout | Number | 0 | special timeout for opening connection, by default equals to timeout
. |
Changelog
Please see CHANGELOG.md.
License
MIT @ Vitaliy Potapov