jellysocket
v1.0.8
Published
JellySocket makes writing your own WebSocket protocols more streamlined.
Downloads
3
Maintainers
Readme
jellysocket
JellySocket is a thin abstraction of a pure WebSocket, providing a streamlined API and reliable error handling. You are expected to extend the JellySocket class to create your own custom protocols. The hard stuff is all taken care of for you. All you have to worry about is the data layer.
JellySocket weighs in at only 2,251 bytes minified and gzipped.
Installation
npm install --save jellysocket
Usage
var JellySocket = require('jellysocket');
function SuperSocket(uri) {
JellySocket.call(this, uri);
this.on('_message', function (ui8Array) {
this.emit('message', ui8Array);
});
}
SuperSocket.prototype.__proto.__ = JellySocket.prototype;
SuperSocket.prototype.protocol = 'super-cool-protocol-1.0';
SuperSocket.prototype.send = function (ui8Array) {
return this._send(ui8Array);
};
An example client:
var supersocket = new SuperSocket('ws://myapp.com/path/to/app');
supersocket.on('message', function (data) {
supersocket.send(data);
});
An example server:
var Application = require('jellysocket').Application;
var app = Application(server, SuperSocket);
app.on('connection', function (supersocket) {
supersocket.send(getUint8Array());
});
The idea is that your subclass hooks into the _message
event and the _send
method, while exposing more useful events and methods as public API.
When you extend the JellySocket class, you must add a string protocol
property to the prototype. This is how your protocol will be identified within the WebSockets subprotocol scheme.
MyCustomSocket.prototype.protocol = 'super-cool-protocol-1.0'
Browser support
Much of jellysocket
's awesomeness comes from her apt use of modern web technologies. She requires WebSocket
with binary support (no legacy versions, only RFC-6455).
Natively, this package is supported by:
- Chrome 16+
- Firefox 11+
- Safari 7+
- Opera 12.1+
- Internet Exporer 10+
- Edge
API
class JellySocket
On the client, these instances can be created by invoking the constructor.
On the server, these instances are exposed by JellySocketApplication in the connection
event.
For non-browser clients, you can pass an optional options
object as a second argument, which will get passed to the underlying ws
module.
.disconnect([error]) -> this
Closes the connection. The disconnect
event is immediately emitted. You can optionally pass an Error
object, which will be exposed in the disconnect
event at both endpoints.
._send(data) -> this
Sends the given data to the other endpoint. Use this method as the underlying transport mechanism for building your own API. This method is not intended to be used by the consumer of your API.
The data
argument must be a Uint8Array
. Since the Node.js Buffer
object inherits from Uint8Array
, you can send those too.
get .connected -> boolean
Indicates if the connection is open and events may be sent back and forth.
get .bufferedAmount -> number
Returns the number of bytes in the internal buffer. In advanced applications, this can be monitered to adjust network usage rates.
JellySocket Events
JellySocket exposes three events:
connect
disconnect
_message
The connect
event is triggered on a client when an open connection has been established and data may be sent back and forth.
The disconnect
event is triggered when the connection has been closed. If it was closed because of an error, the first argument of this event is the associated Error
object (otherwise null).
The _message
event is triggered when the JellySocket receives data. The first argument of this event will be a Uint8Array
of that data. In Node.js, you will get a Buffer
object instead (which inherits from Uint8Array
). This event is intended to be used by your subclass, but not by the users of that subclass.
class JellySocketApplication
On the server only:
var JellySocketApplication = require('jellysocket').Application
var app = new JellySocketApplication(server, MyCustomSocketClass, options)
The server
argument must be a http.Server
or https.Server
object. MyCustomSocketClass
must be a subclass of JellySocket
.
Options
options.path
The path of the WebSocket server.
Default: "/"
options.verifyClient
You may supply a verifyClient function which must return true
for each client wishing to connect to the WebSocket endpoint. The function may have the following two signatures:
function verifyClient(info) { // synchronous
return false
}
function verifyClient(info, cb) { // asynchronous
cb(false, 401, 'Unauthorized')
}
info is an object with the following properties:
- string
info.origin
- boolean
info.secure
- http.IncomingMessage
info.req
options.heartbeat
If this option is set, all clients of an JellySocketApplication
will periodically be sent a heartbeat. If a client endpoint does not respond after too many heartbeats, the connection will be forcefully destroyed. You can set options.heartbeat
to an integer to dictate how frequenty (in seconds) heartbeats are sent. A value of 0
or Infinity
will cause this instance of JellySocketApplication
to not send and track heartbeats.
Default: 0
options.heartbeatForgiveness
This is the maximum number of heatbeats a client can miss before the connection is forcefully destroyed. A value of 0
or Infinity
means clients will never be disconnected as a result of being unresponsive. As an example, if this option is 5
, and options.heartbeat
is 30
, then clients would get disconnected after 150 seconds of unresponsiveness.
Default: 0
.lock() -> this
Prevents new clients from connecting to the websocket endpoint.
.unlock() -> this
Allows new clients to connect to the websocket endpoint. When an JellySocketApplication
instance is created, it starts out unlocked.
.disconnect([error]) -> this
Locks
the JellySocketApplication
, and invokes the .disconnect()
method on each connected client.
get .clients -> Set (read-only)
Returns a read-only Set of the clients that are connected to the JellySocketApplication
. The returned Set is live, meaning its contents will change constantly as clients connect and disconnect. To get a static snapshot of the connected clients, use var clients = new Set(app.clients)
.
get .server -> http.Server
Returns the http(s) server that is associated with this JellySocketApplication
.
get .isLocked -> boolean
Returns whether the JellySocketApplication
is currently rejecting new clients.
JellySocketApplication Events
JellySocketApplication exposes two events:
connection
vacant
The connection
event is triggered when a client successfully connects to the WebSocket server. The first argument of this event will an instance of JellySocket (more specifically, an instance of your subclass of JellySocket).
The vacant
event is triggered when the JellySocketApplication is locked, and no clients are connected.
Notes
By default, when a client tries to connect to your WebSocket server at an unused path, their connection will hang forever. This allows other WebSocket modules to share the same HTTP server by handling different paths. However, if a path is not used by any module, preferably that connection will be ended with a 404 Not Found
response. JellySocket provides a convenient way of doing this.
var JellySocket = require('jellysocket');
server.on('upgrade', JellySocket.Application.upgradeNotFound);
Make sure that JellySocket.Application.upgradeNotFound
is the LAST upgrade
event added to the server.