Socket.io memory leak - node.js

Here is my full node.js code:
var express = require('express'),
http = require("http"),
app = express(),
server = http.createServer(app),
sio = require('socket.io'),
io = null;
server.listen(3000, "localhost");
io = sio.listen(server);
io.sockets.on('connection', function (socket) {
socket.emit('access', "connected");
});
When I check the node.exe process (I'm on localhost windows), every time a user connects, the memory usage increases but every time a user disconnects, the memory usage doesn't decrease. Is something wrong with my setup?

I can also be the redisClient that you use that keeps the reference.
Either try with another redis Client or try setting the redisClient = null; and see if that changes something.
It can also be something else in your code.
You can also try the Node Inspector which run in the Chrome developer tools where you can see the different object that are in memory.

Related

My node socket.io connection get automatically disconnect after a short period of inactivity

I have spent a long on Google but I didn't found any solution. I saw many questions related to my problem on stack overflow but I didn't get any solution.
Explaining in brief, I am coding for real time chat room and it works fine when I continuously send messages from either room but when I left it for a short period mean (when message is not send from either side) it automatically gets disconnect inside the browser is still opened. And messages send from one room didn't transferred to other room. Please help me.
var express = require('express'); // node code
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
var redis = require('redis');
var redis_client = redis.createClient(6379,'192.168.43.49');
redis_client.auth('rajesh');
redis_client.select(1);
io.sockets.on('connection',function(socket){
/* used for transfering message from one node to other node */
socket.on('node_message',function(data){
// sending message to other end
redis_client.smembers(data.user_hash,function(err,reply){
if(reply!=null){
reply.forEach(function(value){
var res = {'user_hash':socket.user_hash,'msg':data.msg};
io.to(value).emit('node_message',res); // i am sending sender user_hash also so that while getting message in second end i will validate second party {cause problem in multi-page to show message in every panel}
});
}
});
});
socket.on('disconnect', function (){
console.log('lost connection',socket.user_hash);
})
});

Nodejs memory usage

I think I have a problem with memory usage. I have a node.js server :
var arcadeGames = require('./server/js/arcade');
var cardsGames = require('./server/js/cards');
requires modules that exports object required from .json data
var http = require('http');
var express = require('express');
var app = express();
var server = http.createServer(app);
//var io = require('socket.io').listen(server);
//var fs = require('fs');
app.get('/specificCategory/:id',function(req,res,next){
switch(req.params.id){
case "Cards":
console.log(cardsGames.titles);
break;
case "Action":
console.log(actionGames.titles);
break;
default:
console.log("undefined");
}
//var specificCaategory = require('./server/js/'+ req.params.id.toLowerCase());
//var categoryTitlesAndUrlThumbs = spe
//console.log(specificCaategory.titles);
})
(both way are working the same commented one or the one with switch)
the get function is called from browser by clicking the categories ex :Cards, Action and send the request through http, controller from angularjs. The problem is that when I console.loged out on server first click on each category works fine, but after that, the server takes a lot of time to console.log out the info.(what will happends in browser if this is so hard for server).
Have I done something to load the memory so much?
Add res.end(); after your switch case.

Socket.IO connection error

I've an application in node.js with socket.io. Everything was running completely fine, but suddenly the browser started to send this error.
failed: Error in connection
establishment:net::ERR_TUNNEL_CONNECTION_FAILED
I didn't make any code change.
The protocol used by socket is ws:// and when I try to use this url in browser
'ws://highgarden-nodejs-91180.sae1.nitrousbox.com/socket.io/?EIO=3&transport=websocket&sid=T9Unec8KbWw-GAL8AAAF'
Chrome returns this error:
Failed to load resource: net::ERR_DISALLOWED_URL_SCHEME
This is a part of the socket setup code:
server.js:
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var port = process.env.PORT || 3000
*------------------------------------------*
// routes ===
var routes = require('./config/routes.js');
var sock = {}
routes(app, passport, sock);
io.sockets.on('connection', sock.update);
// launch ===
server.listen(port);
Thanks advance.
Hi the exception ERR_TUNNEL_CONNECTION_FAILED happens when a tunnel connection through the proxy could not be established. And the ERR_DISALLOWED_URL_SCHEME happens when the scheme of the URL is disallowed.
May you need use it behind the proxy!
Chrome 45.0.2454.101 m says the page has been disabled or moved on the server.

Socket.IO & private messages

This must have been asked already a thousand times, but I do not find any of the answers satisfying, so I'll try having another go, being as clear as possible.
I am starting out with a clean Express; the one that is usually done via the following terminal commands:
user$ express
user$ npm install
then I proceed installing socket.io, this way:
user$ npm install socket.io --save
on my main.js file I then have the following:
//app.js
var express = require('express'),
http = require('http'),
path = require('path'),
io = require('socket.io'),
routes = require('./routes');
var app = express();
I start my socket.io server by attaching it to my express one:
//app.js
var server = http.createServer(app).listen(app.get('port'), function(){
console.log('express server started!');
});
var sIo = io.listen(server);
What I do now is to set the usual routes for Express to work with:
//app.js
app.get('/', routes.index);
app.get('/send/:recipient/:text', routes.sendMessage);
Now, Since I like to keep things organized, I want to put my socket.io code in another file, so instead of using the usual code:
//app.js
sIo.sockets.on('connection', function(socket){
console.log('got a connection');
});
I use the following to be able to access both the socket and the sIo object (as that object contains all the connections infos (important)):
//app.js
sIo.sockets.on('connection', function(socket){
routes.connection(sIo, socket);
});
// index.js (./routes)
exports.connection = function(sIo, socket){
console.log('got a connection.');
};
This way I can do all my socket.io jobs in here. I know that I can access all my clients information now from the sIo object, but of course, they do not contain any information about their session data.
My questions now are the following:
Suppose a user makes an HTTP request to send a message and the handler in my routes is like this:
exports.sendMessage = function(req, res){
//do stuff here
};
How can I get this to "fire" something in my socket.io to send a message? I do not want to know all the underlying work that needs to be done, like keeping track of messages, users, etc. I only want to understand how to "fire" socket.io to do something.
How can I make sure that socket.io sends the message only to a person in particular and be 100% sure that nobody else gets it? From what I can see, there is no way to get the session infos from the sIo object.
Thanks in advance.
question one: The cleanest way to separate the two would probably be to use an EventEmitter. You create an EventEmitter that emits when an http message comes in. You can pass session information along with the event to tie it back to the user who sent the message if necessary.
// index.js (./routes)
var EventEmitter = require('events').EventEmitter;
module.exports.messageEmitter = messageEmitter = new EventEmitter();
module.exports.sendMessage = function(req, res) {
messageEmitter.emit('private_message', req.params.recipient, req.params.text);
};
question 2: You can access the socket when the initial connection is made. An example mostly borrowed from this answer:
var connect = require('connect'),
userMap = {};
routes.messageEmitter.on('private_message', function(recipient, text) {
userMap[recipient].emit('private_message', text);
});
io.on('connection', function(socket_client) {
var cookie_string = socket_client.request.headers.cookie;
var parsed_cookies = connect.utils.parseCookie(cookie_string);
var connect_sid = parsed_cookies['connect.sid'];
if (connect_sid) {
session_store.get(connect_sid, function (error, session) {
userMap[session.username] = socket_client;
});
}
socket_client.on('private_message', function(username, message) {
userMap[username].emit(private_message, message)
});
});
So we're just creating a map between a session's username and a socket connection. Now whenever you need to send a message you can easily lookup what socket is associated with that user and send a message to them using their socket. Just make sure to handle disconnects, and reconnects and connecting in multiple tabs, etc.
I have built something like what you are saying. If a user can make a socket request, it pushes the message via the socket, and then the server does a broadcast or emit of it. But, if a user can't connect to the socket, it then does the http post, like what you are saying by calling the sendMessage. What I have done, rather than having sendMessage shoot off a socket is that I also have my clients doing an ajax request every 5 seconds or so. That will bring back new messages, and if any of the messages were not received via socket.io, I then add them to my clientside array. This acts as sort of a safety net, so I don't have to always fully trust socket.io.
see below in pseudo code
client
if canSendSocketMessage()
sendSocketMessage(message)
else
sendAjaxMessage(message)
setInterval( ->
// ajax call
getNewMessages()
), 5000
server
socket stuff
socket.on 'message' ->
saveMessage()
socket.emit(message)
ajax endpoints
app.post 'sendMessage'
saveMessage()
app.get 'getNewMessages'
res.send getNewMessages()

Node.js cluster module

please help. I'm using nodejs cluster module: http://nodejs.org/docs/v0.6.18/api/cluster.html. I have the following code:
run.js
var cluster = require('cluster');
if (cluster.isMaster) {
require('os').cpus().forEach(function () {
cluster.fork();
});
} else {
require('./worker.js');
}
worker.js
var http = require('http'),
connect = require('connect'),
sio = require('socket.io'),
// create server
app = connect(),
server = http.createServer(app);
server.listenPort(80);
var io = sio.listen(server);
// io.sockets.on ....
All workers listen 80 port. Each connection serves a random worker(?). Can I switch worker, where user has connected?
sorry my bad english
If you really needed to switch you could use sockets / socket.io to communicate between your clusters and send your work around.
Otherwise, you can't. But just curious - why would you want to?
You should look into WebRTC which enables peer-to-peer connection which is great for multi-player games.
My 2 cents.

Resources