• This repository has been archived on 17/Jan/2022
  • Stars
    star
    143
  • Rank 257,007 (Top 6 %)
  • Language
    JavaScript
  • Created almost 9 years ago
  • Updated over 8 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A realtime communication framework for Node.js.

Socket.js

Socket.js is a real-time communication framework for Node.js powered by WebSockets. It has no dependencies.

Introduction

Socket.js is lightweight. The minified client is under 3kb. Contrast this with socket.io, which is 95kb minified.

But it's not a fair comparison. Socket.js relies on WebSockets and does not include any fallback transport mechanisms. So only use it when you can assume WebSocket support in your audience's browsers. Most modern browsers support WebSockets; check here for a compatibility chart.

Socket.js is a well-behaved library. Unlike most event-based communication engines, socket.js will not:

  • ...deliver messages out of order.
  • ...deliver duplicate messages.
  • ...deliver messages after the application thinks the socket has been closed.
  • ...deliver queued up messages before the "reconnect" event is fired in the case of a temporary network failure.
  • ...leak memory in the server or client.
  • ...have undefined or insecure behavior if it receives a malformed or malicious message from a client.

Socket.js will:

  • ...automatically reconnect if the connection is lost, unless it was intentionally closed by the application.
  • ...validate inputs to all methods and fail fast.
  • ...drop messages (and not resend them) if there is a network interruption.

That last point may be surprising to you. If you want messages to be resent in the case of failure, you must build that functionality into your application. The server has no idea if or when the client will come back, so it would have to keep queued messages for some arbitrary TTL and then subsequently vacuum them if the client never reconnects. Then, if the client finally does connect after the queue has been deleted, those messages would be dropped anyway. Socket.js is honest about its behavior: it will start dropping messages immediately if there is a network interruption, and it will start sending new messages once the connection is reestablished.

Socket.js was designed to support many simultaneous connections. If a connection is dropped, the server will not hold references to any queued messages or other data structures for that client. It is up to the client to provide any context needed by the server (e.g., a session ID for some session store) when reconnecting.

Installation

Server

Install socket.js with npm.

npm install socket.js

Client

The minified JavaScript can be found in the root directory of this repository.

<script src="socket.min.js"></script>

Server API

Socket.js exposes a single function:

var socketjs = require('socket.js');

socketjs(httpServer, handler);

httpServer is an instance of http.Server from the Node.js standard library. For example:

var http = require('http');

var server = http.createServer();
server.listen(3000, function() {
  console.log('Listening on port 3000.');
});

handler is a callback that takes two parameters, socket and reconnectData. socket is an object with the following methods:

  • socket.send(type, message) sends a message to the client. type is a string indicating the type of message. message is any value that can be converted to JSON.
  • socket.receive(type, handler) registers a handler for a particular type of message. type is a string, and handler is a function which takes the message as an argument. If handler === null, any existing handler for this message type is removed.
  • socket.close(handler) registers a callback to be invoked when the connection is closed, either intentionally or because of a network interruption. If handler === null, any existing handler for this event is removed. If handler is not provided (or handler === undefined), this method closes the socket.

reconnectData is an optional value provided by the client when it reconnects in the case of a network interruption. If the client does not provide this value, it will be null.

Example server

var http = require('http');
var socketjs = require('socket.js');

// start an http server
var server = http.createServer();
server.listen(3000, function() {
  console.log('Listening on port 3000.');
});

socketjs(server, function(socket, reconnectData) {
  // if we get disconnected and subsequently reconnect, the client can pass data here
  if (reconnectData === null) {
    console.log('A user connected.');
  } else {
    console.log('A user reconnected with: ', reconnectData);
  }

  // log messages as they arrive
  socket.receive('greeting', function(message) {
    console.log('Received:', message);
  });

  // periodically send messages to the client
  var interval = setInterval(function() {
    socket.send('greeting', 'Hello from the server!');
  }, 1000);

  // if the client disconnects, stop sending messages to it
  socket.close(function() {
    console.log('A user disconnected.');

    clearInterval(interval);
  });
});

Client API

Socket.js exposes a top-level object named socketjs with two methods:

  • socketjs.isSupported() returns a boolean indicating whether the browser supports WebSockets.
  • socketjs.connect(host, secure) returns an object representing the connection to the server. host is the name of the host and optionally the port, separated by a colon. secure is a boolean indicating whether to use the WS or the WSS protocol. If these parameters are missing, Socket.js will attempt to connect to the host that served the page, using the same port and security level.

The object returned by socketjs.connect() supports the following methods:

  • send(type, message) sends a message to the server. type is a string indicating the type of message. message is any value that can be converted to JSON.
  • socket.receive(type, handler) registers a handler for a particular type of message. type is a string, and handler is a function which takes the message as an argument. If handler === null, any existing handler for this message type is removed.
  • socket.disconnect(handler) registers a callback to be invoked when the network is interrupted. If handler === null, any existing handler for this event is removed.
  • socket.reconnect(handler) registers a callback to be invoked when the connection is restored after a network interruption. The value returned by the callback will be sent to the server (see reconnectData above). If handler === null, any existing handler for this event is removed.
  • socket.close(handler) registers a callback to be invoked when the connection is closed by either the server or the client. If handler === null, any existing handler for this event is removed. If handler is not provided (or handler === undefined), this method closes the socket.

Example client

// make sure socket.js is supported
if (socketjs.isSupported()) {
  // connect to the server
  var socket = socketjs.connect();

  // log messages as they arrive
  socket.receive('greeting', function(data) {
    console.log('Received:', data);
  });

  // log a message if we get disconnected
  socket.disconnect(function() {
    console.log('Temporarily disconnected.');
  });

  // log a message when we reconnect
  socket.reconnect(function() {
    console.log('Reconnected.');

    // whatever we return here is sent back to the server
    return 'reconnected';
  });

  // periodically send messages the server
  var interval = setInterval(function() {
    socket.send('greeting', 'Hello from the client!');
  }, 1000);

  // if the server disconnects, stop sending messages to it
  socket.close(function() {
    console.log('Connection closed.');

    clearInterval(interval);
  });
} else {
  // let the user know that socket.js is not supported
  console.log('Your browser does not support WebSockets.');
}

Demo

A simple demo is provided. To start the demo, run npm start at the root of this repository and point your browser to http://localhost:3000. The server should start printing messages from the client, and vice versa.

License

Copyright (c) 2016 Stephan Boyer

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

More Repositories

1

toast

Containerize your development and continuous integration environments. 🥂
Rust
1,499
star
2

docuum

Docuum performs least recently used (LRU) eviction of Docker images. 🗑️
Rust
489
star
3

proofs

My personal repository of formally verified mathematics.
Coq
259
star
4

theorem-prover

An automated theorem prover for first-order logic.
Python
225
star
5

tagref

Tagref helps you maintain cross-references in your code.
Rust
148
star
6

hashpass

A simple password manager with a twist.
TypeScript
113
star
7

effects

A brief exploration of the various approaches to modeling side effects in a purely functional programming language.
Haskell
100
star
8

typical

Data interchange with algebraic data types.
Rust
81
star
9

raytracer

A browser-based real-time raytracer written in CoffeeScript.
CSS
53
star
10

data-structure-explorer

A web-based pedagogical tool for exploring data structures.
JavaScript
48
star
11

cfg-checker

Search for ambiguities in context-free grammars.
C++
38
star
12

unicode

Portable ASCII and Unicode string manipulation functions for C++.
C++
21
star
13

doesgoogleexecutejavascript

Google executes JavaScript, even if the script is fetched from the network. However, Google does not make AJAX requests.
JavaScript
15
star
14

dotfiles

My configuration files.
Shell
13
star
15

paxos

An implementation of single-decree Paxos.
Rust
10
star
16

dubstepn

My personal blog.
Ruby
9
star
17

base16-circus-scheme

A theme for the Base16 color system.
6
star
18

gigamesh

A home for all your notes.
TypeScript
6
star
19

coq-intro

An introduction to proving theorems and certifying programs with Coq.
Coq
5
star
20

gigamesh-schema

The Typical schema for the Gigamesh data model.
Perl
3
star
21

stem-cell

A simple project to demonstrate the cross-platform release management process I use for my open source work.
Shell
3
star
22

subjunct

A website for sharing secrets.
Ruby
3
star
23

garnet

A fast and minimalist template engine for Node.
JavaScript
2
star
24

webpack-scaffolding

Scaffolding for building web applications.
JavaScript
2
star
25

gists

Small projects that don't deserve their own repository.
Python
1
star