3

I am trying to create a simple chat App with Node.JS and Websocket using Socket.IO. I inspired myself by this German tutorial and for the single backend instance it works well.

I would like to have 2 instances of the server in the backend, which should sync the chat messages between each other and store the chat history in redis. The client should display the last 10 messages from the current channel, when new chat-room is joined.

I tried to apply the solution from this stackoverflow page but I get some issues. First I get

WebSocket connection to 'ws://localhost:8080/socket.io/?EIO=3&transport=websocket&sid=LEqGvY0CVk9YaSzBAAAA' failed: Connection closed before receiving a handshake response

error in the console. And second, both clients are receiving the 'payload' messages in the 1-sec interval. I probably do not understand how the redis-sync mechanism works and I also do not yet know how to display the chat history.

Here is my code so far:

var conf = require('./config.json');
var cluster = require('cluster');
var os = require('os');

if (cluster.isMaster) {
  // we create a HTTP server, but we do not use listen
  // that way, we have a socket.io server that doesn't accept     connections
  var server = require('http').createServer();
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

    io.adapter(redis({ host: conf.redisUri, port: conf.redisPort }));

  setInterval(function() {
    // all workers will receive this in Redis, and emit
    io.emit('chat', {time: new Date(), text:'payload'});
  }, conf.syncIntervall);

// set number of workers
  for (var i = 0; i < conf.numberOfWorkers; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
}

if (cluster.isWorker) {
  var express = require('express');
  var app = express();

  var http = require('http');
  var server = http.createServer(app);
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

    // Webserver
    //app.listen(conf.defaultPort);
    server.listen(conf.defaultPort);

    // deliver static files
    app.use(express.static(__dirname + '/public'));
    // route for the / path
    app.get('/', function (req, res) {
        // send the index.html in the reponse
        res.sendfile(__dirname + '/public/index.html');
    });

    // Websocket

    io.adapter(redis({ host: conf.redisUri, port: conf.redisPort }));
    // Callback when a client connects
    io.sockets.on('connection', function (socket) {
    // store the room name in the socket session for this client
    socket.room = 'defaultChannel';
    // send client to room 1
    socket.join('defaultChannel');
    // echo to client they've connected
    socket.emit('chat', { time: new Date(), text: 'You have connected to room defaultChannel on the server!' });
    socket.emit('chat', { time: new Date(), text: 'Connected to chat worker-node: ' + cluster.worker.id});
    // if a message is received
    socket.on('chat', function (data) {
        // the it will be send to all other clients
        console.log('the current channel', socket.room);
        socket.broadcast.in(socket.room).emit('chat', { time: new Date(), name: data.name || 'anonymous', text: data.text });
    });
    // if a client joins a channel
    socket.on('join', function (room) {
    // store the room name in the socket session for this client
    socket.room = room;
    // send client to room 1
    socket.join(room);
    console.log('Client joined room ' + room);
    });
});

// Log port number in the console
console.log('Server running under http://127.0.0.1:' + conf.defaultPort + '/');

}
Community
  • 1
  • 1
karlitos
  • 1,604
  • 3
  • 27
  • 59
  • It might useful : http://goldfirestudios.com/blog/136/Horizontally-Scaling-Node.js-and-WebSockets-with-Redis – Mahesh K Oct 27 '16 at 16:24

0 Answers0