Socket.io, cluster, express and sync events

血红的双手。 提交于 2019-12-04 02:47:29

From that source : http://socket.io/docs/using-multiple-nodes/

If you plan to distribute the load of connections among different processes or machines, you have to make sure that requests associated with a particular session id connect to the process that originated them.

This is due to certain transports like XHR Polling or JSONP Polling relying on firing several requests during the lifetime of the “socket”.

To route connections to the same worker every time :

sticky-session

This is, in the socket.io documentation, the recommended way to route requests to the same worker every time.

https://github.com/indutny/sticky-session

A simple performant way to use socket.io with a cluster.

Socket.io is doing multiple requests to perform handshake and establish connection with a client. With a cluster those requests may arrive to different workers, which will break handshake protocol.

var sticky = require('sticky-sesion');

sticky(function() {
  // This code will be executed only in slave workers

  var http = require('http'),
      io = require('socket.io');

  var server = http.createServer(function(req, res) {
    // ....
  });
  io.listen(server);

  return server;
}).listen(3000, function() {
  console.log('server started on 3000 port');
});

To pass messages between nodes :

socket.io-redis

This is, in socket.io documentation, the recommended way to share messages between workers.

https://github.com/automattic/socket.io-redis

By running socket.io with the socket.io-redis adapter you can run multiple socket.io instances in different processes or servers that can all broadcast and emit events to and from each other.

socket.io-redis is used this way :

var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));

Also

I think you are not using socket.io v1.0.0. You might want to update your version in order to get more stability.

You can check their migration guide at http://socket.io/docs/migrating-from-0-9/

Squivo

There is a step missing from the socket.io docs when using

var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));

You need to tell the client that you want to use 'websockets' as the only form of transport or it will not work... so for the constructor on the client use

io.connect(yourURL , { transports : ['websocket']});

see my answer to a similar question here ( my answer might be more appropriate on this thread ): https://stackoverflow.com/a/30791006/4127352

The below code work for me, this is socket.io who created clusters, i set config.clusterSticky on true for activate compatibility clusters and socket.io

'use strict';

/*
 var cl = console.log;
 console.log = function(){
 console.trace();
 cl.apply(console,arguments);
 };
 */

var cluster = require('cluster'),
    config = require('./config/all'),
    deferred = require('q').defer(),
    express = require('express'),
    app = express(),
    http = require('http'),
    sticky = require('socketio-sticky-session'),
    io = require('socket.io');

// Code to run if we're in the master process or if we are not in debug mode/ running tests

if ((cluster.isMaster) &&
    (process.execArgv.indexOf('--debug') < 0) &&
    (process.env.NODE_ENV !== 'test') && (process.env.NODE_ENV !== 'development') &&
    (process.execArgv.indexOf('--singleProcess') < 0) &&
    (!config.clusterSticky)) {

    console.log('for real!');
    // Count the machine's CPUs
    var cpuCount = process.env.CPU_COUNT || require('os').cpus().length;

    // Create a worker for each CPU
    for (var i = 0; i < cpuCount; i += 1) {
        console.log('forking ', i);
        cluster.fork();
    }

    // Listen for dying workers
    cluster.on('exit', function (worker) {
        // Replace the dead worker, we're not sentimental
        console.log('Worker ' + worker.id + ' died :(');
        cluster.fork();
    });

// Code to run if we're in a worker process
} else {
    var port = config.http.port;
    var workerId = 0;
    if (!cluster.isMaster) {
        workerId = cluster.worker.id;
    }

    var server = http.createServer(app);
    io.listen(server);

    //TODO routes etc (core)

    server.on('listening', function () {
        console.log('Slave app started on port ' + port + ' (' + process.env.NODE_ENV + ') cluster.worker.id:', workerId);
    });

    if(config.clusterSticky && (process.env.NODE_ENV !== 'test') && (process.env.NODE_ENV !== 'development')) {
        sticky(server).listen(port);
    } else {
        server.listen(port);
    }

    deferred.resolve(server);
}

module.exports = deferred.promise;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!