Socket
Socket
Sign inDemoInstall

sockjs

Package Overview
Dependencies
13
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    sockjs


Version published
Weekly downloads
11M
increased by6.02%
Maintainers
1
Install size
153 kB
Created
Weekly downloads
 

Package description

What is sockjs?

SockJS is a JavaScript library that provides a WebSocket-like object in environments where true WebSockets are not available or not fully supported. It is designed to work both on the client-side and server-side to enable seamless communication between the two. SockJS provides a consistent API and attempts to provide a low-latency, full duplex, cross-domain communication channel that can work even behind restrictive corporate proxies.

What are sockjs's main functionalities?

Server-side WebSocket emulation

This code sample demonstrates how to create a SockJS server that emulates a WebSocket. It listens for connections on the '/echo' path and simply echoes back any messages it receives.

const http = require('http');
const sockjs = require('sockjs');
const echo = sockjs.createServer({ prefix: '/echo' });
echo.on('connection', function(conn) {
  conn.on('data', function(message) {
    conn.write(message);
  });
});
const server = http.createServer();
echo.installHandlers(server, { prefix: '/echo' });
server.listen(9999, '0.0.0.0');

Client-side WebSocket emulation

This code sample shows how to create a SockJS client that connects to a SockJS server. It sends a message when the connection is opened and logs any messages it receives before closing the connection.

const SockJS = require('sockjs-client');
let sock = new SockJS('http://localhost:9999/echo');
sock.onopen = function() {
  console.log('open');
  sock.send('test');
};
sock.onmessage = function(e) {
  console.log('message', e.data);
  sock.close();
};
sock.onclose = function() {
  console.log('close');
};

Other packages similar to sockjs

Readme

Source

SockJS family:

  • SockJS-client JavaScript client library
  • SockJS-node Node.js server
  • SockJS-erlang Erlang server

SockJS-node server

SockJS-node is a Node.js server side counterpart of SockJS-client browser library written in CoffeeScript.

To install sockjs-node run:

npm install sockjs

An simplified echo SockJS server could look more or less like:

var http = require('http');
var sockjs = require('sockjs');

var echo = sockjs.createServer(sockjs_opts);
echo.on('connection', function(conn) {
    conn.on('data', function(message) {
        conn.write(message);
    });
    conn.on('close', function() {});
});

var server = http.createServer();
echo.installHandlers(server, {prefix:'[/]echo'});
server.listen(9999, '0.0.0.0');

(Take look at examples directory for a complete version.)

Subscribe to SockJS mailing list for discussions and support.

Live QUnit tests and smoke tests

SockJS-client comes with some QUnit tests and a few smoke tests that are using SockJS-node. At the moment they are deployed in few places:

SockJS-node API

The API design is based on the common Node API's like Streams API or Http.Server API.

Server class

SockJS module is generating a Server class, similar to Node.js http.createServer module.

var sockjs_server = sockjs.createServer(options);

Where options is a hash which can contain:

sockjs_url (string, required)
Transports which don't support cross-domain communication natively ('eventsource' to name one) use an iframe trick. A simple page is served from the SockJS server (using its foreign domain) and is placed in an invisible iframe. Code run from this iframe doesn't need to worry about cross-domain issues, as it's being run from domain local to the SockJS server. This iframe also does need to load SockJS javascript client library, and this option lets you specify its url (if you're unsure, point it to the latest minified SockJS client release, this is the default). You must explicitly specify this url on the server side for security reasons - we don't want the possibility of running any foreign javascript within the SockJS domain (aka cross site scripting attack). Also, sockjs javascript library is probably already cached by the browser - it makes sense to reuse the sockjs url you're using in normally.
prefix (string)
A url prefix for the server. All http requests which paths begins with selected prefix will be handled by SockJS. All other requests will be passed through, to previously registered handlers.
disabled_transports (list of strings)
A list of streaming transports that should not be handled by the server. This may be useful when it's known that the server stands behind a load balancer which doesn't like some streaming transports, for example websockets. The only valid transport currently is: 'websocket'.
response_limit (integer)
Most streaming transports save responses on the client side and don't free memory used by delivered messages. Such transports need to be garbage-collected once in a while. `response_limit` sets a minimum number of bytes that can be send over a single http streaming request before it will be closed. After that client needs to open new request. Setting this value to one effectively disables streaming and will make streaming transports to behave like polling transports. The default value is 128K.
jsessionid (boolean or function)
Some hosting providers enable sticky sessions only to requests that have JSESSIONID cookie set. This setting controls if the server should set this cookie to a dummy value. By default setting JSESSIONID cookie is enabled. More sophisticated beaviour can be achieved by supplying a function.
log (function(severity, message))
It's quite useful, especially for debugging, to see some messages printed by a SockJS-node library. This is done using this `log` function, which is by default set to `console.log`. If this behaviour annoys you for some reason, override `log` setting with a custom handler. The following `severities` are used: `debug` (miscellaneous logs), `info` (requests logs), `error` (serious errors, consider filing an issue).
heartbeat_delay (milliseconds)
In order to keep proxies and load balancers from closing long running http requests we need to pretend that the connecion is active and send a heartbeat packet once in a while. This setting controlls how often this is done. By default a heartbeat packet is sent every 25 seconds.
disconnect_delay (milliseconds)
The server sends a `close` event when a client receiving connection have not been seen for a while. This delay is configured by this setting. By default the `close` event will be emitted when a receiving connection wasn't seen for 5 seconds.

Server instance

Once you have create Server instance you can hook it to the http.Server instance.

var http_server = http.createServer();
sockjs_server.installHandlers(http_server, options);
http_server.listen(...);

Where options can overshadow options given when creating Server instance.

Server instance is an EventEmitter, and emits following event:

Event: connection (connection)
A new connection has been successfully opened.

All http requests that don't go under the path selected by prefix will remain unanswered and will be passed to previously registered handlers. You must install your custom http handlers before calling installHandlers.

Connection instance

A Connection instance supports Node Stream API and has following methods and properties:

Property: readable (boolean)
Is the stream readable?
Property: writable (boolean)
Is the stream writable?
Property: remoteAddress (string)
Last known IP address of the client.
Property: remotePort (number)
Last known port number of the client.
Property: address (object)
Hash with 'address' and 'port' fields.
Property: headers (object)
Hash containing various headers copied from last receiving request on that connection. Exposed headers include: `origin`, `referer` and `x-forwarded-for` (and friends). We expliclty do not grant access to `cookie` header, as using it may easily lead to security issues.
Property: url (string)
Url property copied from last request.
Property: pathname (string)
`pathname` from parsed url, for convenience.
Property: prefix (string)
Prefix of the url on which the request was handled.
write(message)
Sends a message over opened connection. A message must be a non-empty string. It's illegal to send a message after the connection was closed (either after 'close' or 'end' method or 'close' event).
close([code], [reason])
Asks the remote client to disconnect. 'code' and 'reason' parameters are optional and can be used to share the reason of disconnection.
end()
Asks the remote client to disconnect with default 'code' and 'reason' values.

A Connection instance emits the following events:

Event: data (message)
A message arrived on the connection. Message is a unicode string.
Event: close ()
Connection was closed. This event is triggered exactly once for every connection.

For example:

sockjs_server.on('connection', function(conn) {
    console.log('connection' + conn);
    conn.on('close', function() {
        console.log('close ' + conn);
    });
    conn.on('data', function(message) {
        console.log('message ' + conn,
                    message);
    });
});

Footnote

A fully working echo server does need a bit more boilerplate (to handle requests unanswered by SockJS), see the echo example for a complete code.

Examples

If you want to see samples of running code, take a look at:

Deployment and load balancing

There are two issues that needs to be considered when planning a non-trivial SockJS-node deployment: WebSocket-compatible load balancer and sticky sessions (aka session affinity).

WebSocket compatible load balancer

Often WebSockets don't play nicely with proxies and loadbalancers. Deploying a SockJS server behind Nginx or Apache could be painful.

Fortunetely recent versions of an excellent loadbalancer HAProxy are able to proxy WebSocket connections. We propose to put HAProxy as a front line load balancer and use it to split SockJS traffic from normal HTTP data. Take a look at the sample SockJS HAProxy configuration.

The config also shows how to use HAproxy balancing to split traffic between multiple Node.js servers. You can also do balancing using dns names.

Sticky sessions

If you plan depling more than one SockJS server, you must make sure that all HTTP requests for a single session will hit the same server. SockJS has two mechanisms that can be usefull to achieve that:

  • Urls are prefixed with server and session id numbers, like: /resource/<server_number>/<session_id>/transport. This is usefull for load balancers that support prefix-based affinity (HAProxy does).
  • JSESSIONID cookie is being set by SockJS-node. Many load balancers turn on sticky sessions if that cookie is set. This technique is derived from Java applications, where sticky sessions are often neccesary. HAProxy does support this method, as well as some hosting providers, for example CloudFoundry. In order to enable this method on the client side, please supply a cookie:true option to SockJS constructor.

Development

If you want to update SockJS-node source code, clone git repo and follow this steps. First you need to install dependencies:

cd sockjs-node
npm install --dev

You're ready to compile CoffeeScript to js:

make

If you want to automatically recompile when the source files are modified, take a look at make serve. Make sure your changes to SockJS-node don't break test code in SockJS-client and don't break the SockJS-protocol test suite.

FAQs

Last updated on 06 Dec 2011

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc