This is a general-purpose WebSocket implementation extracted from the Faye project. It provides classes for easily building WebSocket servers and clients in Node. It does not provide a server itself, but rather makes it easy to handle WebSocket connections within an existing Node application. It does not provide any abstraction other than the standard WebSocket API.
It also provides an abstraction for handling EventSource connections, which are one-way connections that allow the server to push data to the client. They are based on streaming HTTP responses and can be easier to access via proxies than WebSockets.
Installation
$ npm install faye-websocket
Handling WebSocket connections in Node
You can handle WebSockets on the server side by listening for HTTP Upgrade requests, and creating a new socket for the request. This socket object exposes the usual WebSocket methods for receiving and sending messages. For example this is how you'd implement an echo server:
var WebSocket = require('faye-websocket'),
http = require('http');
var server = http.createServer();
server.on('upgrade', function(request, socket, body) {
if (WebSocket.isWebSocket(request)) {
var ws = new WebSocket(request, socket, body);
ws.on('message', function(event) {
ws.send(event.data);
});
ws.on('close', function(event) {
console.log('close', event.code, event.reason);
ws = null;
});
}
});
server.listen(8000);
WebSocket
objects are also duplex streams, so you could replace the
ws.on('message', ...)
line with:
ws.pipe(ws);
Note that under certain circumstances (notably a draft-76 client connecting
through an HTTP proxy), the WebSocket handshake will not be complete after you
call new WebSocket()
because the server will not have received the entire
handshake from the client yet. In this case, calls to ws.send()
will buffer
the message in memory until the handshake is complete, at which point any
buffered messages will be sent to the client.
If you need to detect when the WebSocket handshake is complete, you can use the
onopen
event.
If the connection's protocol version supports it, you can call ws.ping()
to
send a ping message and wait for the client's response. This method takes a
message string, and an optional callback that fires when a matching pong message
is received. It returns true
if and only if a ping message was sent. If the
client does not support ping/pong, this method sends no data and returns
false
.
ws.ping('Mic check, one, two', function() {
// fires when pong is received
});
Using the WebSocket client
The client supports both the plain-text ws
protocol and the encrypted wss
protocol, and has exactly the same interface as a socket you would use in a web
browser. On the wire it identifies itself as hybi-13
.
var WebSocket = require('faye-websocket'),
ws = new WebSocket.Client('ws://www.example.com/');
ws.on('open', function(event) {
console.log('open');
ws.send('Hello, world!');
});
ws.on('message', function(event) {
console.log('message', event.data);
});
ws.on('close', function(event) {
console.log('close', event.code, event.reason);
ws = null;
});
The WebSocket client also lets you inspect the status and headers of the
handshake response via its statusCode
and headers
properties.
To connect via a proxy, set the proxy
option to the HTTP origin of the proxy,
including any authorization information, custom headers and TLS config you
require. Only the origin
setting is required.
var ws = new WebSocket.Client('ws://www.example.com/', [], {
proxy: {
origin: 'http://username:password@proxy.example.com',
headers: {'User-Agent': 'node'},
tls: {cert: fs.readFileSync('client.crt')}
}
});