How to reverse proxy a Socket.io app with Nginx? - node.js

I want to reverse proxy the official Socket.io chat demo with Nginx.
So, this is the server file:
// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('../..')(server);
var port = process.env.PORT || 3000;
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
// Routing
app.use(express.static(__dirname + '/public'));
// Chatroom
var numUsers = 0;
io.on('connection', function (socket) {
var addedUser = false;
// when the client emits 'new message', this listens and executes
socket.on('new message', function (data) {
// we tell the client to execute 'new message'
socket.broadcast.emit('new message', {
username: socket.username,
message: data
});
});
// when the client emits 'add user', this listens and executes
socket.on('add user', function (username) {
if (addedUser) return;
// we store the username in the socket session for this client
socket.username = username;
++numUsers;
addedUser = true;
socket.emit('login', {
numUsers: numUsers
});
// echo globally (all clients) that a person has connected
socket.broadcast.emit('user joined', {
username: socket.username,
numUsers: numUsers
});
});
// when the client emits 'typing', we broadcast it to others
socket.on('typing', function () {
socket.broadcast.emit('typing', {
username: socket.username
});
});
// when the client emits 'stop typing', we broadcast it to others
socket.on('stop typing', function () {
socket.broadcast.emit('stop typing', {
username: socket.username
});
});
// when the user disconnects.. perform this
socket.on('disconnect', function () {
if (addedUser) {
--numUsers;
// echo globally that this client has left
socket.broadcast.emit('user left', {
username: socket.username,
numUsers: numUsers
});
}
});
});
and this is the client side code:
$(function() {
var FADE_TIME = 150; // ms
var TYPING_TIMER_LENGTH = 400; // ms
var COLORS = [
'#e21400', '#91580f', '#f8a700', '#f78b00',
'#58dc00', '#287b00', '#a8f07a', '#4ae8c4',
'#3b88eb', '#3824aa', '#a700ff', '#d300e7'
];
// Initialize variables
var $window = $(window);
var $usernameInput = $('.usernameInput'); // Input for username
var $messages = $('.messages'); // Messages area
var $inputMessage = $('.inputMessage'); // Input message input box
var $loginPage = $('.login.page'); // The login page
var $chatPage = $('.chat.page'); // The chatroom page
// Prompt for setting a username
var username;
var connected = false;
var typing = false;
var lastTypingTime;
var $currentInput = $usernameInput.focus();
var socket = io();
function addParticipantsMessage (data) {
var message = '';
if (data.numUsers === 1) {
message += "there's 1 participant";
} else {
message += "there are " + data.numUsers + " participants";
}
log(message);
}
// Sets the client's username
function setUsername () {
username = cleanInput($usernameInput.val().trim());
// If the username is valid
if (username) {
$loginPage.fadeOut();
$chatPage.show();
$loginPage.off('click');
$currentInput = $inputMessage.focus();
// Tell the server your username
socket.emit('add user', username);
}
}
// Sends a chat message
function sendMessage () {
var message = $inputMessage.val();
// Prevent markup from being injected into the message
message = cleanInput(message);
// if there is a non-empty message and a socket connection
if (message && connected) {
$inputMessage.val('');
addChatMessage({
username: username,
message: message
});
// tell server to execute 'new message' and send along one parameter
socket.emit('new message', message);
}
}
// Log a message
function log (message, options) {
var $el = $('<li>').addClass('log').text(message);
addMessageElement($el, options);
}
// Adds the visual chat message to the message list
function addChatMessage (data, options) {
// Don't fade the message in if there is an 'X was typing'
var $typingMessages = getTypingMessages(data);
options = options || {};
if ($typingMessages.length !== 0) {
options.fade = false;
$typingMessages.remove();
}
var $usernameDiv = $('<span class="username"/>')
.text(data.username)
.css('color', getUsernameColor(data.username));
var $messageBodyDiv = $('<span class="messageBody">')
.text(data.message);
var typingClass = data.typing ? 'typing' : '';
var $messageDiv = $('<li class="message"/>')
.data('username', data.username)
.addClass(typingClass)
.append($usernameDiv, $messageBodyDiv);
addMessageElement($messageDiv, options);
}
// Adds the visual chat typing message
function addChatTyping (data) {
data.typing = true;
data.message = 'is typing';
addChatMessage(data);
}
// Removes the visual chat typing message
function removeChatTyping (data) {
getTypingMessages(data).fadeOut(function () {
$(this).remove();
});
}
// Adds a message element to the messages and scrolls to the bottom
// el - The element to add as a message
// options.fade - If the element should fade-in (default = true)
// options.prepend - If the element should prepend
// all other messages (default = false)
function addMessageElement (el, options) {
var $el = $(el);
// Setup default options
if (!options) {
options = {};
}
if (typeof options.fade === 'undefined') {
options.fade = true;
}
if (typeof options.prepend === 'undefined') {
options.prepend = false;
}
// Apply options
if (options.fade) {
$el.hide().fadeIn(FADE_TIME);
}
if (options.prepend) {
$messages.prepend($el);
} else {
$messages.append($el);
}
$messages[0].scrollTop = $messages[0].scrollHeight;
}
// Prevents input from having injected markup
function cleanInput (input) {
return $('<div/>').text(input).text();
}
// Updates the typing event
function updateTyping () {
if (connected) {
if (!typing) {
typing = true;
socket.emit('typing');
}
lastTypingTime = (new Date()).getTime();
setTimeout(function () {
var typingTimer = (new Date()).getTime();
var timeDiff = typingTimer - lastTypingTime;
if (timeDiff >= TYPING_TIMER_LENGTH && typing) {
socket.emit('stop typing');
typing = false;
}
}, TYPING_TIMER_LENGTH);
}
}
// Gets the 'X is typing' messages of a user
function getTypingMessages (data) {
return $('.typing.message').filter(function (i) {
return $(this).data('username') === data.username;
});
}
// Gets the color of a username through our hash function
function getUsernameColor (username) {
// Compute hash code
var hash = 7;
for (var i = 0; i < username.length; i++) {
hash = username.charCodeAt(i) + (hash << 5) - hash;
}
// Calculate color
var index = Math.abs(hash % COLORS.length);
return COLORS[index];
}
// Keyboard events
$window.keydown(function (event) {
// Auto-focus the current input when a key is typed
if (!(event.ctrlKey || event.metaKey || event.altKey)) {
$currentInput.focus();
}
// When the client hits ENTER on their keyboard
if (event.which === 13) {
if (username) {
sendMessage();
socket.emit('stop typing');
typing = false;
} else {
setUsername();
}
}
});
$inputMessage.on('input', function() {
updateTyping();
});
// Click events
// Focus input when clicking anywhere on login page
$loginPage.click(function () {
$currentInput.focus();
});
// Focus input when clicking on the message input's border
$inputMessage.click(function () {
$inputMessage.focus();
});
// Socket events
// Whenever the server emits 'login', log the login message
socket.on('login', function (data) {
connected = true;
// Display the welcome message
var message = "Welcome to Socket.IO Chat – ";
log(message, {
prepend: true
});
addParticipantsMessage(data);
});
// Whenever the server emits 'new message', update the chat body
socket.on('new message', function (data) {
addChatMessage(data);
});
// Whenever the server emits 'user joined', log it in the chat body
socket.on('user joined', function (data) {
log(data.username + ' joined');
addParticipantsMessage(data);
});
// Whenever the server emits 'user left', log it in the chat body
socket.on('user left', function (data) {
log(data.username + ' left');
addParticipantsMessage(data);
removeChatTyping(data);
});
// Whenever the server emits 'typing', show the typing message
socket.on('typing', function (data) {
addChatTyping(data);
});
// Whenever the server emits 'stop typing', kill the typing message
socket.on('stop typing', function (data) {
removeChatTyping(data);
});
socket.on('disconnect', function () {
log('you have been disconnected');
});
socket.on('reconnect', function () {
log('you have been reconnected');
if (username) {
socket.emit('add user', username);
}
});
socket.on('reconnect_error', function () {
log('attempt to reconnect has failed');
});
});
I tried this Nginx configuration:
location /myapp/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
But im getting the following errors when i link to localhost/myapp:
http://localhost/socket.io/socket.io.js Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost/main.js Failed to load resource: the server responded with a status of 404 (Not Found)
Can someone please help me?

You have specified a location of /myapp/ in the nginx config but you haven't updated the html page to reference files at this location (http://localhost/myapp/*).

Related

New connection cause the current connections to stop working

I am making the chat application using socket (which I'm new at) with multiple tenants structure and using namespaces. Here's my code:
Socket server:
index.js
class Server {
constructor() {
this.port = process.env.PORT || 3000;
this.host = process.env.HOST || `localhost`;
this.app = express();
this.http = http.Server(this.app);
this.rootSocket = socketio(this.http);
}
run() {
new socketEvents(this.rootSocket).socketConfig();
this.app.use(express.static(__dirname + '/uploads'));
this.http.listen(this.port, this.host, () => {
console.log(`Listening on ${this.host}:${this.port}`);
});
}
}
const app = new Server();
app.run();
socket.js
var redis = require('redis');
var redisConnection = {
host: process.env.REDIS_HOST,
password: process.env.REDIS_PASS
};
var sub = redis.createClient(redisConnection);
var pub = redis.createClient(redisConnection);
class Socket {
constructor(rootSocket) {
this.rootIo = rootSocket;
}
socketEvents() {
/**
* Subscribe redis channel
*/
sub.subscribe('visitorBehaviorApiResponse');
//TODO: subscribe channel..
// Listen to redis channel that published from api
sub.on('message', (channel, data) => {
data = JSON.parse(data);
console.log(data);
const io = this.rootIo.of(data.namespace);
if (channel === 'visitorBehaviorApiResponse') {
io.to(data.thread_id).emit('receiveBehavior', data);
io.to('staff_room').emit('incomingBehavior', data);
}
})
sub.on('error', function (error) {
console.log('ERROR ' + error)
})
var clients = 0;
this.rootIo.on('connection', (rootSocket) => {
clients++;
console.log('root:' + rootSocket.id + ' connected (total ' + clients + ' clients connected)');
const ns = rootSocket.handshake['query'].namespace;
// Dynamic namespace for multiple tenants
if (typeof (ns) === 'string') {
const splitedUrl = ns.split("/");
const namespace = splitedUrl[splitedUrl.length - 1];
const nsio = this.rootIo.of(namespace);
this.io = nsio;
this.io.once('connection', (socket) => {
var visitors = [];
console.log('new ' + socket.id + ' connected');
// once a client has connected, we expect to get a ping from them saying what room they want to join
socket.on('createChatRoom', function (data) {
socket.join(data.thread_id);
if (typeof data.is_staff !== 'undefined' && data.is_staff == 1) {
socket.join('staff_room');
} else {
if (visitors.some(e => e.visitor_id === data.visitor_id)) {
visitors.forEach(function (visitor) {
if (visitor.visitor_id === data.visitor_id) {
visitor.socket_ids.push(socket.id);
}
})
} else {
data.socket_ids = [];
data.socket_ids.push(socket.id);
visitors.push(data);
}
socket.join('visitor_room');
}
//TODO: push to redis to check conversation type
});
socket.on('sendMessage', function (data) {
console.log(data);
pub.publish('chatMessage', JSON.stringify(data));
this.io.in(data.thread_id).emit('receiveMessage', data);
this.io.in('staff_room').emit('incomingMessage', data);
// Notify new message in room
data.notify_type = 'default';
socket.to(data.thread_id).emit('receiveNotify', data);
}.bind(this))
socket.on('disconnect', (reason) => {
sub.quit();
console.log('client ' + socket.id + ' left, ' + reason);
});
socket.on('error', (error) => {
console.log(error);
});
});
}
// Root disconnect
rootSocket.on('disconnect', function () {
clients--;
console.log('root:' + rootSocket.id + ' disconnected (total ' + clients + ' clients connected)');
});
});
}
socketConfig() {
this.socketEvents();
}
}
module.exports = Socket;
Client:
const server = 'https://socket-server'
const connect = function (namespace) {
return io.connect(namespace, {
query: 'namespace=' + namespace,
resource: 'socket.io',
transports: ['websocket'],
upgrade: false
})
}
const url_string = window.location.href
const url = new URL(url_string)
const parameters = Object.fromEntries(url.searchParams)
const socket = connect(`${server}/${parameters.shopify_domain}`)
var handleErrors = (err) => {
console.error(err);
}
socket.on('connect_error', err => handleErrors(err))
socket.on('connect_failed', err => handleErrors(err))
socket.on('disconnect', err => handleErrors(err))
The problem that I met is when socket server got a new connection, the existing connections will be stopped working util they make a page refreshing to reconnect a new socket.id.
And when a namespace's client emit data, it sends to other namespaces, seem my code is not work correctly in a namespace.
Could you take a look at my code and point me where I'm wrong?
Thanks
1) Get UserId or accessToken while handshaking(in case of accessToken decrypt it).
and store userID: socketId(in Redis or in local hashmap) depends upon the requirement .
2) When u are going to emit to particular user fetch the socketid to that userid from redis or local hashmap
and emit to it.
**io.to(socketId).emit('hey', 'I just met you');**
3) If you are using multiple servers use sticky sessions
4) Hope this will help you

Using socket.io in modules and routes Express

I am having some issues using socket.io is modules. I have changed the way I do it quite drastically, however everything seems to be working, except being able to send userdata back to my socket connection:
Here is my io.js file: /config/io
/*jshint esversion: 6*/
var io = require('socket.io')();
const moment = require('moment');
// Socket stuff
io.on('connection', function (socket) {
socket.on('login', function (userdata) {
socket.handshake.session.userdata = userdata;
socket.handshake.session.save();
console.log(socket.handshake.session.userdata);
});
// Server Time
var interval = setInterval(function () {
var momentNow = moment();
var data = momentNow.format('LT');
socket.emit('time', data);
}, 60000);
// Chat - Needs work
socket.on('chat', function (msg) {
console.log(msg);
var username = 'Message'; //socket.handshake.session.userdata.username;
var message = '[' + moment().format('LT') + '] ' + username + ': ' + msg;
io.emit('message', message, username);
});
socket.on('disconnect', function () {
if (socket.handshake.session.userdata) {
delete socket.handshake.session.userdata;
socket.handshake.session.save();
}
console.log('user disconnected');
});
});
module.exports = io;
Here is where I'm trying to emit the data /config/passport: (please note that userdata does indeed contain the right information!)
/*jshint esversion: 6 */
const LocalStrategy = require('passport-local').Strategy;
const db = require('../config/db');
const bcrypt = require('bcryptjs');
var io = require('./io');
module.exports = function(passport) {
// Local Strategy login
passport.use(new LocalStrategy(function(username, password, done) {
// Match Username
let sql = 'SELECT * FROM users WHERE username = ?';
db.query(sql, [username], function(err, rows) {
if (err)
return done(err);
if (!rows.length) {
return done(null, false, {
type: 'loginMessage',
message: 'Wrong Login',
});
}
// Match Password
bcrypt.compare(password, rows[0].password, function(err, isMatch) {
if (err)
return done(err);
if (isMatch) {
var userdata = rows[0];
io.emit('login', userdata); // HERE IS WHERE I TRY TO EMIT IT
// console.log(rows[0]);
return done(null, rows[0]);
} else {
return done(null, false, {
type: 'loginMessage',
message: 'Wrong Login',
});
}
});
});
}));
Now here is my main app file: (leaving out a bunch of stuff)
var io = require('./config/io');
// Init App
const app = express();
// Init http server
const server = http.createServer(app);
// Attach IO
io.attach(server);
// Listen
server.listen(8080, function () {
console.log('Server listening on port 8080...');
});
Now, everything seems to be working fine, except being able to emit the data. Now I tried logging it client side as well (just in case it was emitting on client-side and not server-side) but it is not doing that as well.
Okay, so here is an actual working answer. It s a work-around, and I completely abandoned trying to do it from the passport login handler itself. But here is how I did it:
IO code:
var session = socket.handshake.session;
socket.on('login', function () {
if (socket.handshake.session.passport === undefined) {
var destination = '/';
socket.emit('not logged', destination);
} else {
console.log('user logged in');
var userId = session.passport.user;
var sql = 'SELECT * FROM users WHERE id = ?';
var query = db.query(sql, userId, function (err, rows) {
session.userdata = rows[0];
session.save();
var dataObj = session.userdata;
socket.emit('sart up', dataObj);
});
}
});
And jQuery:
// Connection Successful
socket.on('connect', function () {
connected = true;
socket.emit('login');
});
socket.on('disconnect', function () {
connected = false;
});
socket.on('not logged', function (destination) {
window.location.href = destination;
});
socket.on('start up', function (dataObj) {
});
I'm not a huge fan of having to do it this way, I would have liked to handle everything sever-sided, but for now this is working, and will use until I figure out how to do it the way I'd like to.

I get length 1 even It didn't connect to socket

let app = require('express')(),
http = require('http').Server(app),
User = require('../models/users');
http.listen(8080, function () {
console.log('Socket IO server has been started on port 8080');
});
let io = require('socket.io')(http);
var socketRoom = {};
io.of('/chat').on('connection', function (socket) {
var ioRooms = io.of('/chat').adapter.rooms;
console.log(ioRooms) // I got length 1 when I print it.
socket.on('requestRandomChat', function (data) {
User.findOne({userToken : data.userToken}, function(err, user){
if(err) socket.emit('db error');
if(!user) socket.emit('db error : user not found');
else {
socket.emit('responseUserProfile', user);
for (var key in rooms){
if (key == ''){
continue;
}
if (rooms[key].length == 1){
var roomKey = key.replace('/', '');
socket.join(roomKey);
io.sockets.in(roomKey).emit('completeMatch', {});
socketRoom[socket.id] = roomKey;
return;
}
}
socket.join(user.userToken);
socketRoom[user.userToken] = socket.userToken;
}
});
});
socket.on('cancelRequest', function (data) {
socket.leave(socketRoom[socket.id]);
console.log(ioRooms);
});
socket.on('sendMessage', function (data) {
console.log(ioRooms);
console.log('sendMessage!');
io.of('/chat').in(socketRoom[socket.id]).emit('receiveMessage', data);
});
socket.on('disconnect', function (data) {
console.log(ioRooms);
var key = socketRoom[socket.id];
socket.leave(key);
io.of('/chat').in(key).emit('disconnect');
var clients = io.of('/chat').clients(key);
for (var i = 0; i < clients.length; i++) {
clients[i].leave(key);
}
});
});
when I trying to get a length of rooms, I get a length 1 with a socketId.
but I've never connected to the room. Is that default room? can somebody explain what's happening with the room socket?
//{ '/chat#2HAMaavywIwZ1B5fAAAD': Room { sockets: {
'/chat#2HAMaavywIwZ1B5fAAAD': true }, length: 1 } }
In socket io each socket is automatically connected to a default room identified by socket ID.
That's why you get length 1.
I hope you find it helpful.
http://socket.io/docs/rooms-and-namespaces/

How to create online users list using webrtc and nodejs on the server end

I am using webrtc to make a audio, video and chat application where I need keep all the users in a user list in the serverside. Need help how to get this done.
Also, how can I remove users from the list when they logout from the system.
Need help to implement this.
webRTC.rtc.on('connect', function(rtc) {
//Client connected
});
webRTC.rtc.on('send answer', function(rtc) {
//answer sent
});
webRTC.rtc.on('disconnect', function(rtc) {
//Client disconnect
//console.log(webRTC);
});
webRTC.rtc.on('chat_msg', function(data, socket) {
var roomList = webRTC.rtc.rooms[data.room] || [];
for (var i = 0; i < roomList.length; i++) {
var socketId = roomList[i];
if (socketId !== socket.id) {
var soc = webRTC.rtc.getSocket(socketId);
if (soc) {
soc.send(JSON.stringify({
"eventName": "receive_chat_msg",
"data": {
"messages": data.messages,
"id": data.id,
"from": data.from,
"status": data.status,
"email": data.email
}
}), function(error) {
if (error) {
console.log(error);
}
});
}
}
}
});
As I was using webrtc.io module, so below are the methods that helped me to create the userlist and maintain the presence.
webRTC.rtc.on('join_room', function(data, socket) {
// Will get info who joined along with his socket id
}
And
webRTC.rtc.on('room_leave', function(room, socketid) {
// Will get info who left the room
}
Node.js code:
var users = {};
io.sockets.on('connection', function (socket) {
socket.emit('connect', true);
socket.on('message', function (data) {
socket.broadcast.emit('message', data);
});
socket.on('new-user', function (username) {
users[username] = username;
});
socket.on('check-presence', function (username) {
var isUserPresent = !! users[username];
socket.emit('presence', isUserPresent);
});
socket.on('remove-user', function (username) {
var user = users[username];
if (user) delete users[username];
});
});
This may also work (node.js):
var users = {};
io.sockets.on('connection', function (socket) {
var UserName;
socket.emit('connect', true);
socket.on('message', function (data) {
socket.broadcast.emit('message', data);
});
socket.on('new-user', function (username) {
users[username] = username;
UserName = username;
});
socket.on('check-presence', function (username) {
var isUserPresent = !! users[username];
socket.emit('presence', isUserPresent);
});
// removing user on "disconnect"
socket.on('disconnect', function () {
var user = users[UserName];
if (user) delete users[UserName];
});
});
For 1st case; client-side code:
var socket = io.connect();
socket.on('connect', function () {
socket.emit('new-user', 'username');
});
function removeUser() {
socket.emit('remove-user', 'username');
}
window.onbeforeunload = function () {
removeUser();
};
// if someone pressed "F5" key to refresh the page
window.onkeyup = function (e) {
if (e.keyCode == 116)
removeUser();
};
// if someone leaves via <a href>
var anchors = document.querySelectorAll('a'),
length = anchors.length;
for (var i = 0; i < length; i++) {
var a = anchors[i];
if (a.href.indexOf('#') !== 0 && a.getAttribute('target') != '_blank')
a.onclick = function () {
removeUser();
};
}
For 2nd case; client side code:
var socket = io.connect();
socket.on('connect', function () {
socket.emit('new-user', 'username');
});
You can check presence too:
socket.on('presence', isUserPresent) {
// boolean: user is present or not
});
socket.emit('check-presence', 'username');

running nodejs from cli gives error ENOTFOUND

Below is my nodejs script. All of a sudden running it with: sudo NODE_ENV=test node server.js gives:
info - socket.io started
{ [Error: getaddrinfo ENOTFOUND]
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
fatal: true
}
What can I do to debug ?
var iniparser = require('iniparser');
var config = iniparser.parseSync('../Config/init/db.ini');
var env = process.env.NODE_ENV || 'dev'; //startup nodejs with e.g: NODE_ENV=test forever start server.js
var app = require('http').createServer(handler),
io = require('socket.io').listen(app),
fs = require('fs'),
mysql = require('mysql'),
connectionsArray = [],
connection = mysql.createConnection({
host: config[env]['host'],
user: config[env]['user'],
password: config[env]['pwd'].replace(/"/g, ''),
database: config[env]['dbname']
}),
POLLING_INTERVAL = 1000,
pollingTimer;
// If there is an error connecting to the database
connection.connect(function (err) {
// connected! (unless `err` is set)
console.log(err);
});
// creating the server ( localhost:8000 )
app.listen(1443);
// on server started we can load our client.html page
function handler(req, res) {
fs.readFile(__dirname + '/client.html', function (err, data) {
if (err) {
console.log(err);
res.writeHead(500);
return res.end('Error loading client.html');
}
res.writeHead(200);
res.end(data);
});
}
/*
*
* HERE IT IS THE COOL PART
* This function loops on itself since there are sockets connected to the page
* sending the result of the database query after a constant interval
*
*/
var pollingLoop = function () {
// Doing the database query ap.line_state != 0 means busy
var query = connection.query('SELECT p.id, ap.* FROM active_player ap LEFT JOIN player p ON ap.dossier_id=p.dossier_id '),
players = []; // this array will contain the result of our db query
// setting the query listeners
query
.on('error', function (err) {
// Handle error, and 'end' event will be emitted after this as well
console.log(err);
console.log("ENDPOINT", this.request.httpRequest.endpoint);
updateSockets(err);
})
.on('result', function (player) {
// it fills our array looping on each user row inside the db
players.push(player);
})
.on('end', function () {
// loop on itself only if there are sockets still connected
if (connectionsArray.length) {
pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL);
updateSockets({players: players});
}
});
};
function is(a, b) {
return a === b && (a !== 0 || 1 / a === 1 / b) // false for +0 vs -0
|| a !== a && b !== b; // true for NaN vs NaN
}
// creating a new websocket to keep the content updated without any AJAX request
io.sockets.on('connection', function (socket) {
console.log('Number of connections:' + connectionsArray.length);
// starting the loop only if at least there is one user connected
if (!connectionsArray.length) {
pollingLoop();
}
socket.on('disconnect', function () {
var socketIndex = connectionsArray.indexOf(socket);
console.log('socket = ' + socketIndex + ' disconnected');
if (socketIndex >= 0) {
connectionsArray.splice(socketIndex, 1);
}
});
console.log('A new socket is connected!');
connectionsArray.push(socket);
});
var updateSockets = function (data) {
// adding the time of the last update
data.time = new Date();
// sending new data to all the sockets connected
connectionsArray.forEach(function (tmpSocket) {
tmpSocket.volatile.emit('notification', data);
});
};
For get fully information about exceptions replace
console.log(err);
To:
console.err(err.stack)
And add if for err variable in connecttion.connect callback function.
Also you can add this code, for safy catch all exceptions:
process.on('uncaughtException', function globalErrorCatch(error, p){
console.error(error);
console.error(error.stack);
});

Resources