Reputation: 15
I have a NodeJS that host a WebSocket Server. The WebSocket redistributes message from Redis.
The full line is, i have some python script that push some data in Redis and after that NodeJS is the WebSocket that reads the Redis newly input data to the connected clients. My problem is that the NodeJs is always taking up memory and after a while it just burst and stops.
I don't know what is my problem, since my code is pretty simple.
I don't need my WebSocket to receive message from the connected clients, since i only need to push them data, but alot of data.
var server = require('websocket').server,
http = require('http');
var redis = require("redis"),
client = redis.createClient();
var socket = new server({
httpServer: http.createServer().listen(443),
keepalive: false
});
client.subscribe("attack-map-production");
socket.on('request', function(request) {
var connection = request.accept(null, request.origin);
connection.on('message', function(message) {
console.log(message);
client.on("message", function(channel, message){
connection.send(message);
});
});
connection.on('close', function(connection) {
console.log('connection closed');
});
});
I'm looking to make this work without eating all the memory on my server and possibly make this much more fast, but i think it's fast enough.
Maybe NodeJS is not meant for this kind of work?
Any help is appreciated. Thanks.
Update 2016-11-08
With the information provided below, i have "updated" my code. The problem is still there, i will continue to look around to find a answer... but i'm really not getting this.
var server = require('websocket').server,
http = require('http');
var redis = require("redis"),
client = redis.createClient();
var socket = new server({
httpServer: http.createServer().listen(443),
keepalive: false
});
client.subscribe("attack-map-production");
socket.on('request', function(request) {
var connection = request.accept(null, request.origin);
client.on("message", function(channel, message){
connection.send(message);
});
connection.on('close', function(connection) {
console.log('connection closed');
});
});
Update 2016-11-16
So here is my new code:
var io = require('socket.io').listen(443);
var sub = require('redis').createClient();
io.sockets.on('connection', function (sockets) {
sockets.emit('message',{Hello: 'World!'});
sub.subscribe('attack-map-production'); // Could be any patterni
sockets.on('disconnect', function() {
sub.unsubscribe('attack-map-production');
});
});
sub.on('message', function(channel, message) {
io.sockets.json.send(message);
});
Even this code, makes nodejs go at 100% CPU and even more, and it starts to go really slow, until everything just stops.
The complet flow of my data, is that a python script pushes data into Redis, and throught my subscribtion it pushes my data back to the browser by a webSocket and Socket.io.
That simple, how can this be slow? I just don't get it.
Upvotes: 1
Views: 4283
Reputation: 847
client = redis.createClient();
take a look at this line , everytime you invoke the variable client , you create an instance of redis client inside node , and you never close it. so if you recieve 10000 socket 'request' , you will also have 10000 redis instances.
You need to call the command client.quit() once the write or the read to redis is done
var server = require('websocket').server,
http = require('http');
var redis = require("redis"),
client = redis.createClient();
var socket = new server({
httpServer: http.createServer().listen(443),
keepalive: false
});
client.subscribe("attack-map-production");
socket.on('request', function(request) {
var connection = request.accept(null, request.origin);
client.on("message", function(channel, message){
connection.send(message);
});
client.quit(); // MISSING LINE
connection.on('close', function(connection) {
console.log('connection closed');
});
});
and i also noticed this piece of code
httpServer: http.createServer().listen(443)
the port 443 is for https ! so if you are using a secured connection you need to call the module https not http, like this
var socket = new server({
httpServer: https.createServer().listen(443),
keepalive: false
});
hope it helps !
Upvotes: 2
Reputation: 3543
Maybe NodeJS is not meant for this kind of work?
If node is meant for something it's this. I/O stream and reading/writing is the main advantage of node asynchronism.
On what kind of server are you running this ? In a too small EC2 instance you can hit some memory problem.
Else it's a leak. That's kind of hard to trace.
Code is small thought.
I would remove any console.log just in case.
connection.on('message', function(message) {
console.log(message);
client.on("message", function(channel, message){
connection.send(message);
});
});
This part feel suspicious, two variables with the same name, an unused variable, it calls for trouble, and I don't really get why you have to listen for connection message in order to wait for redis message.
Upvotes: 1