4

I'm very new to node.js (generally beginner in server issues).

I managed to run my node.js app and put it online on my virtual server (Linux 8.0).

The problem is that node.js opens a lot of TCP sockets. After some time the number of allowed sockets is exhausted and the server crashes. I currently have to manually stop and restart the node process to prevent this. The restarting resets the TCP sockets.

I need to find a solution for this issue because restarting it manually is not a long term fix, especially if the number of visitors will increase and I probably would need to restart it every 12 hours (which is just not practical).

I am probably doing something wrong in the coding but I currently have no idea what I can optimize. I'm happy that it even works. Which part of the code is creating all these TCP connection? How can I solve this?

My node file/app does the following:

  • send/emits messages to an open and/or private chat.
  • send/emits invitation for a game (type of game is not important)
  • if invite accepts invitation both 'clients' are send to the same room and game starts

nodeServer.js

var socket = require( 'socket.io' ); var express = require( 'express' ); var http = require( 'http' ); var app = express(); var server = http.createServer( app ); var io = socket.listen( server ); // handle incoming connections from clients io.sockets.on( 'connection', function( client ) { // Message Emit for match invite client.on( 'sendmatchinvite', function( data ) { console.log( 'Match invite for '+data.opponent+' from '+data.sender); client.broadcast.emit('sendmatchinvite', { tmpmatch:data.tmpmatch, recepient: data.opponent, sender: data.sender } ); }); // Answer of invite client.on( 'checkinviteanswer', function( data ) { console.log( 'Invitation '+data.answer+' from '+data.id+' in '+data.room); client.broadcast.to(data.room).emit('checkinviteanswer', { host:data.host } ); }); // Register Room client.on('room', function(room) { console.log( 'Client joined the room: '+room); client.join(room); }); // Score Emit for online games client.on( 'score', function( data ) { console.log( 'New Score for "'+data.game+'" (from '+data.player+') : ' + data.score + ' (Undo='+data.undo+') in room '+data.room); client.broadcast.to(data.room).emit('score', { game:data.game, score: data.score, undo: data.undo, player: data.player } ); }); // Message Emit for private chat client.on( 'privatemessage', function( data ) { console.log( 'New Message for "'+data.recepient+'" (from '+data.sender+') : ' + data.text); client.broadcast.emit('privatemessage', { text:data.text, recepient: data.recepient, sender: data.sender } ); }); // Message Emit for Player Room (all) client.on( 'openmessage', function( data ) { console.log( 'New Message for "Player Room" (from '+data.senderId+') : ' + data.text); client.broadcast.emit('openmessage', { text:data.text, senderId:data.senderId, senderAvatar:data.senderAvatar, senderName:data.senderName, senderAvg:data.senderAvg, senderCam:data.senderCam, senderTimestamp:data.senderTimestamp, senderTime:data.senderTime } ); }); }); server.listen( 8080 ); 

If I do a lsof -ni -P to see connection there are indeed a lot of lines by node

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ... node 13855 root 273u IPv4 33761866321 0t0 TCP 83.256.77.109:8080->84.60.76... (ESTABLISHED) node 13855 root 275u IPv4 33781428883 0t0 TCP 83.256.77.109:8080->94.197.121...(ESTABLISHED) node 13855 root 276u IPv4 33937034956 0t0 TCP 83.256.77.109:8080->79.195.169... (ESTABLISHED) node 13855 root 278u IPv4 33971290522 0t0 TCP 83.256.77.109:8080->111.254.157... (ESTABLISHED) node 13855 root 279u IPv4 33198279063 0t0 TCP 83.256.77.109:8080->91.48.115... (ESTABLISHED) ... 

EDIT 1

I should note that I use php pages. On all php pages which needs the node app I do a connection to the node server.

var socket = io.connect( 'http://example.com:8080' ); socket.on('connect', function( data ) { }); 

I'm not sure if this is the right way to go, because on every refresh of the page the connection is closed and re-established.

2
  • You need to close your connection, either on the server or on the client (or both) when no longer needed. Commented Mar 27, 2015 at 16:21
  • Thanks for your answer, I thought the connections (sockets) are closed automatically once the client leave the site (or page which connects to the server), but apparently not. How can I force the closing? Commented Mar 28, 2015 at 11:21

1 Answer 1

0

First, make sure to configure your server correctly. A modern linux has conservative defaults that aren't tuned for high simultaneous connections. There are some pointers here:

How many socket connections possible?

Second, make sure you have a way to 'kick' users off. For example, someone may connect from their cell phone or laptop in a coffee shop, then turn their device off. The TCP connection can remain open for hours or days if there is no traffic. If you don't actively detect them, they will slowly choke off all your valid TCP connections.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer, will have a look at my server settings. How can I 'kick off' the users.
Enable "TCP keepalive" and/or make sure there is a "heart-beat" check going over the connection every few minutes, and close the connection if no data is seen.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.