unisocket
v0.10.1
Published
A node.js server implementation of the UniSocket communication protocol.
Downloads
3
Readme
UniSocket Server
This is a Node.js server for UniSocket. It supports the entire UniSocket specification, including channels and replies.
Getting Started
First thing first, you will need to npm install unisocket
. Then, it's as simple as:
var UniSocketServer = require('../unisocket');
var socketServer = new UniSocketServer().listen(4000);
For a completely working example, check out the example directory.
Configuration
Currently, configuration isn't used. This will change in the very near future.
You can pass configuration options to the UniSocketServer
instance when you instantiate it:
var UniSocketServer = require('../unisocket');
var socketServer = new UniSocketServer({ timeout: 4000 });
Starting a server
There are two ways to start a UniSocket server. Either by calling listen()
, or attach()
. The difference is that
listen()
starts its own http server. This server (available on the UniSocketServer instance as httpServer
) is used
to serve the client javascript, and to attach the websocket server to.
If all you need is websockets, then you can simple do:
var UniSocketServer = require('../unisocket');
var socketServer = new UniSocketServer()
var socketServer.listen(4000);
Attaching to an existing server
If, like most applications, you instead will need to server http content as well as using websockets, you will need to
call attach
. All you need to pass it is the already listening http server you created yourself.
var http = require('http);
var UniSocketServer = require('../unisocket');
var httpServer = http.createServer().listen(4000);
var socketServer = new UniSocketServer().attach(httpServer);
Using a Connect-style server
Using it with connect is just as simple as attaching to an existing http server.
var http = require('http');
var connect = require('connect');
var UniSocketServer = require('../unisocket');
var app = connect()
.use(connect.logger('dev'))
.use(connect.static('public'))
.use(function(req, res){
res.end('hello world\n');
});
var httpServer = http.createServer(app).listen(4000);
var socketServer = new UniSocketServer().attach(httpServer);
Alternatively, you can use it with connect without creating an http server by hand.
var connect = require('connect');
var UniSocketServer = require('../unisocket');
var server = connect()
.use(connect.logger('dev'))
.use(connect.static('public'))
.use(function(req, res){
res.end('hello world\n');
}).listen(4000);
var socketServer = new UniSocketServer().attach(server);
Using the served client-side library
UniSocket Server conveniently serves the client-side javascript for your application. It is highly recommended you use the served version, as it has been tested with the version of UniSocket Server you've installed. Using a different version could introduce bugs, or other issues.
In order to use the served javascript, simply add the following to your html page:
<script src="/unisocket/$/client.js"></script>
Then, using it is as simple as:
<script>
var socket = unisocket.connect();
socket.on('connected', function()
{
console.log('connected.');
socket.emit('Hello World!');
});
</script>
Listening for messages
Once you've connected, you will want to listen for incoming messages, and respond to them. If you've ever used Socket.io before, this should look familiar:
socketServer.on('connection', function(client)
{
client.on('test', function(data)
{
console.log('got data:', data);
});
});
A couple of points to mention, however. First, you must listen for the connection
event, and setup all of your
handlers inside of the callback for that event. The only argument passed to the connection
event is a
UniSocketClient
instance; this is the object that emits events for incoming messages. You need to listen for events on
this object, if you want to be notified about incoming messages.
Event callbacks will be passed any additional arguments the message was sent with. (If a reply is desired, the last argument will always be a callback. See "Replies" for more information.)
Sending messages
Sending messages is as simple as emitting an event in node. (We've intentionally use the same API as EventEmitter
since this is a common pattern for node.js developers.)
client.emit('test', "Some additional data.");
You can pass as many arguments as you want, and they will be passed to the client's message handler callback.
Complete (Basic) Example
//----------------------------------------------------------------------------------------------------------------------
// A simple example server.
//
// @module server.js
//----------------------------------------------------------------------------------------------------------------------
var UniSocketServer = require('../unisocket');
//----------------------------------------------------------------------------------------------------------------------
var socketServer = new UniSocketServer().listen(4000);
socketServer.on('connection', function(client)
{
client.on('test', function(msg)
{
console.log('got:', msg);
});
});
console.log('Server started.');
//----------------------------------------------------------------------------------------------------------------------
Features
In addition to the basic usage, UniSocket Server supports some very useful features.
Using Channels
UniSocket supports namespacing messages. These namespaces are called 'channels'. (Socket.io has a very similar feature.) If you want to use channels, both the client and server side will need to listen on the same channel. To setup message handlers on a particular channel, you would do the following:
socketServer.channel('/example', function(client)
{
client.on('test', function(data)
{
console.log('got data:', data);
});
});
Instead of listening for the connection
event, you instead register a callback for the /example
channel. Then, when
the client connects to that channel, your callback will be called, and your message handlers registered. Besides that
slight change, everything works exactly the same.
(See the example folder for a client/server that uses channels.)
Using Replies
Frequently, it's useful to be able to reply to an incoming message (or get a reply back from the client). UniSocket makes this as easy as possible, and unlike Socket.io, replies are bi-directional. The client can send a message, and the server can reply, or the server can send a message, and the client reply. The API is intentionally identical on both sides.
Note: Replies have a configurable timeout, however, that timeout cannot be infinite. If a reply is expected, the other side should always respond.
Expecting a reply
If your message expects a reply, the final argument to emit
must be a callback. This callback function will be called
when the reply comes in, with any arguments included in the reply.
client.emit('expects reply', "some data", function(replyData)
{
console.log('responseData:', responseData);
});
Replying to a message
Replying to a message is also very straightforward. When a message comes in to the server that expects a reply, the UniSocket Server builds a callback for you, and appends that to the list of arguments your message handler function gets passed. This means the last argument is always the callback.
To reply, simply call the callback, with whatever data you wish to send back.
socketServer.on('connection', function(client)
{
client.on('echo', function(msg, callback)
{
// Echo msg back to the client.
callback(msg);
});
});
Tips
While the UniSocket Server is pretty simple to work with, there are some additional useful tips I felt might be important to give examples of.
Broadcasts
To do a broadcast, simply iterate over all the clients connected to the server:
socketServer.clients.forEach(function(client)
{
// Put your broadcast message here.
client.emit('broadcast');
});
Message names with spaces
UniSocket and UniSocket Server support message names with spaces in them. This means you can use phrases and sentence fragments to describe the message; making it easier to understand what the message does. Here's an example:
// Here's a single word message
client.emit('edit');
// Here's a message with underscores
client.emit('edit_blog');
// Here's a sentence fragment, with spaces
client.emit('edit blog post');
Personally, I find the last example the most readable, and encourage people to use UniSocket like that.
Note: There is one small caveat: some server implementations (like Erlang) might require a bit of syntactic sugar to support message names with spaces. However, the specification states that any valid unicode character is supported in a message name, so all compliant servers must have a way of handling this. It's just useful to keep this in mind.
Tests
UniSocket Server has a complete suite of tests. Just run:
$ npm test
Contributions
Feel free to make pull requests, fix bugs, add features, etc. We ask that all pull requests maintain the formatting and style of the original file, and that all new features include tests. We reserve the right to refuse any features that do not fit the project's goals.
License
All code is licensed under the MIT license.