【问题标题】:Socket.io websocket authorization failing when clustering node application集群节点应用程序时 Socket.io websocket 授权失败
【发布时间】:2012-03-03 22:35:32
【问题描述】:

问题:是否可以集群使用 Socket.io 来支持 WebSocket 的应用程序?如果是这样,最好的实施方法是什么?

我已经构建了一个使用 Express 和 Socket.io、基于 Node.js 的应用程序。我想加入集群以增加我的应用程序可以处理的请求数量。

以下导致我的应用程序产生套接字握手错误...

var cluster = require('cluster');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('death', function(worker) {
    console.log('worker ' + worker.pid + ' died');
  });
} else {
  app.listen(3000);  
}

控制台日志显示 socket.io 正在多次启动。

jack@jack:~$ node nimble/app.js
   info  - socket.io started
   info  - socket.io started
   info  - socket.io started
   info  - socket.io started
   info  - socket.io started
   info  - socket.io started
   info  - socket.io started
   info  - socket.io started
   info  - socket.io started

Socket.io 目前正在我的服务器代码顶部使用:

var io = require('socket.io').listen(app);

websocket授权码:

//Auth the user
io.set('authorization', function (data, accept) {
  // check if there's a cookie header
  if (data.headers.cookie) {
    data.cookie = parseCookie(data.headers.cookie);
    data.sessionID = data.cookie['express.sid'];

    //Save the session store to the data object
    data.sessionStore = sessionStore;

    sessionStore.get(data.sessionID, function(err, session){
      if(err) throw err;

      if(!session)
      {
        console.error("Error whilst authorizing websocket handshake");
        accept('Error', false);
      }
      else
      {
        console.log("AUTH USERNAME: " + session.username);
        if(session.username){
          data.session = new Session(data, session);
          accept(null, true);
        }else {
          accept('Invalid User', false);
        }       

      }
    })
  } else {
    console.error("No cookie was found whilst authorizing websocket handshake");
    return accept('No cookie transmitted.', false);
  }
});

错误信息的控制台日志:

Error whilst authorizing websocket handshake
   debug - authorized
   warn  - handshake error Error

【问题讨论】:

    标签: javascript node.js socket.io cluster-computing


    【解决方案1】:

    你的sessionStore 是什么?如果是connect 附带的MemoryStore,则不会在您的工作人员之间共享会话。每个工作人员都有自己的一组会话,如果客户端连接到另一个工作人员,您将找不到他们的会话。我建议你看看例如connect-redis 用于在进程之间共享会话。基本用法:

    var connect = require('connect')
      , RedisStore = require('connect-redis')(connect);
    
    var app = connect.createServer();
    app.use(connect.session({store: new RedisStore, secret: 'top secret'});
    

    当然,这需要你也设置redis。在 Connect wiki 有 CouchDB、memcached、postgres 等模块。

    不过,这只能解决您的部分问题,因为现在您在工作人员之间共享会话,但socket.io 无法向连接到其他工作人员的客户端发送消息。基本上,如果您在一个工作人员中发出socket.emit,则该消息将仅发送到连接到同一工作人员的客户端。对此的一种解决方案是将RedisStore 用于socket.io,它利用redis 在worker 之间路由消息。基本用法:

    var sio = require('socket.io')
      , RedisStore = sio.RedisStore
      , io = sio.listen(app);
    
    io.set('store', new RedisStore);
    

    现在,所有消息都应该路由到客户端,无论它们连接到什么工作人员。

    另见:Node.js, multi-threading and Socket.io

    【讨论】:

      猜你喜欢
      • 2015-01-23
      • 1970-01-01
      • 2021-05-27
      • 2023-01-30
      • 2017-01-21
      • 2016-07-12
      • 2021-12-15
      • 1970-01-01
      • 2019-05-19
      相关资源
      最近更新 更多