React and Reflux usage in real-time applications based on websockets (Part 2 — Server side application)

Before reading this story it’s strongly recommended to take a look at Part 1. Client application is described in Part 3.

Server related npm packages

Nothing special here — just socket.io library to setup simple WebSocket server using node JS. Also all babel-related packages are presented in order to make our server work with all ES6 features.

Server app initialization and main variables

First of all we need to import all external modules required for our WebSocket server — node http and socket.io modules, then we create socket.io WebSocket server.

import http from ‘http’;
import io from ‘socket.io’;
let socketServer = io(http);

After that we need to initialize variables — items to store items used for sending updates and number range to determine range of numbers we send via WebSocket (let’s define range from 1 to 100). Usage of those variables will be explained later.

//items we need to send updates for
let items = [];
//numbers from one to 100
const range = 100;

Launch WebSocket server to listen port 3001 of localhost

socketServer.listen(3001, () => {
console.log(‘listening on *:3001’);
});

Define subscribe and unsubscribe functions to add/remove element from the items array

const unsubscribe = (id) => { //unsubscribe from selected id
let index = items.indexOf(id);
if (index > -1) {
items.splice(index, 1);
return true;
}
return false;
};
const subscribe = (id) => { //subscribe for selected id
let index = items.indexOf(id);
if (index === -1) {
items.push(id);
return true;
}
return false;
};

Another function will generate random number for specific item it

const updateNumberMessage = () => { //update random id with number
return {
id: items[Math.floor(Math.random() * items.length)],
number: Math.floor(Math.random() * range),
};
};

Then we are going to implement WebSocket logic itself as the following set of methods. All WebSocket-related logic should work after successful connection from the client to WebSocket server

socketServer.on(‘connection’, (socket) => {
/* all websocket-related logic lives here */
}

When the client is successfully subscribed to WebSocket updates we start sending update packages every 2 seconds (we update random item with random number from 1 to 100). If we have an error we stop sending any updates and clear interval.

 socket.on(‘subscribe’, (data, fn) => {
if (typeof data.ids !== ‘undefined’ && data.ids.length) {
items = data.ids;
fn();
if (!interval) {
interval = setInterval(() => {
socketServer.emit(‘update’, updateNumberMessage());
}, 2000);
}
} else { //emit error message
socketServer.emit(‘error’,
{error: ‘Error! Malformed subscribe package!’});
clearInterval(interval);
}
});

Socket.io on() method calls a callback on named event. Callback accepts 2 parameters — data (sent as event payload) and function, called acknowledgement callback, which works when the client confirmed the message reception.

If we receive disable action for one of items— we remove that id from items array to stop sending updates for that item. After successful action we send back an answer that specific item has changed its status to ‘disabled’ and doesn’t receive updates anymore.

socket.on(‘disable’, (data) => {
if (typeof data.id === ‘undefined’) {
return false;
}
if (unsubscribe(data.id)) {
socketServer.emit(‘status’, {id: data.id, status: ‘disabled’});
}
return false;
});

For subscribe action we do the opposite — add item to array and send message to the WebSocket about successful enabling of the specific item

socket.on(‘enable’, (data) => {
if (typeof data.id === ‘undefined’) {
return false;
}
if (subscribe(data.id)) {
socketServer.emit(‘status’, {id: data.id, status: ‘enabled’});
}
return false;
});

Full code of server-side app can be found here. To test server side app pull the repository, go to server folder, run npm install to get all required packages, them you can start server in dev mode using npm start command from command line.