简体   繁体   English

Node.JS,Socket.IO和Clusters中的WebSocket握手不起作用

[英]WebSocket handshake in Node.JS, Socket.IO and Clusters not working

I having a problem with clustering my application with Node.js, socket.io and node.js clusters. 我在使用Node.js,socket.io和node.js集群集群我的应用程序时遇到问题。

I using the socket.io-redis to share the information for all workers, but is not working. 我使用socket.io-redis来共享所有工作人员的信息,但是无法正常工作。

My code: 我的代码:

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('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {

    ...

         var express   = require("express");
         //Server
         var server = express();
         //Socket.io
         var http  = require('http').Server(server);
         var io    = require('socket.io')(http);
         var redis_io = require('socket.io-redis'); 
         var redis = require("redis");

         io.adapter(redis_io({host: "127.0.0.1", port: 6379 })); 

    ...
}

In client, i get errors in handshake like 400 error or WebSocket is closed before the connection is established. 在客户端,我得到握手错误,如400错误或WebSocket在建立连接之前关闭。

What i can do to solve this? 我能做些什么来解决这个问题?

Im using the last version of node.js and socket.io 我使用的是node.js和socket.io的最新版本

Thanks! 谢谢!

I had this same problem and it took me a while to figure it out. 我遇到了同样的问题,我花了一段时间才弄明白。 A bit of research explained that it is because some of the transports, like long-polling, need to make multiple requests in order to establish the optimal connection. 一些研究解释说,这是因为一些传输,如长轮询,需要发出多个请求才能建立最佳连接。 There is state held across requests, so if different consecutive requests get routed to different cluster workers, the connection fails. 跨请求存在状态,因此如果将不同的连续请求路由到不同的集群工作程序,则连接将失败。

There is a page about it at http://socket.io/docs/using-multiple-nodes/ which cites a custom cluster module called sticky-session which works around this: https://github.com/indutny/sticky-session http://socket.io/docs/using-multiple-nodes/上有一个关于它的页面,它引用了一个名为sticky-session的自定义cluster模块,该模块可以解决这个问题: https//github.com/indutny/sticky-会议

I really did not want to use it since that basically ignores all the work the node.js team has been investing in the TCP load balancing behind the cluster module. 我真的不想使用它,因为这基本上忽略了node.js团队一直投资于集群模块后面的TCP负载平衡的所有工作。

Since the Web Socket protocol itself only needs a single connection, I was able to work around this by forcing websocket to be the first and only transport. 由于Web Socket协议本身只需要一个连接,因此我可以通过强制websocket成为第一个也是唯一的一个传输来解决这个问题。 I can do this because I control the client and server. 我可以这样做,因为我控制客户端和服务器。 For a public web page, this may not be safe for you to do since you have to worry about browser compatibility. 对于公共网页,这可能不安全,因为您不得不担心浏览器兼容性。 In my case, the client is a mobile app. 就我而言,客户端是一个移动应用程序。

Here is the JavaScript client code I put into my test page (again, the real client is a mobile app, so my web page here is really just an aid to help build and test): 这是我放入测试页面的JavaScript客户端代码(同样,真正的客户端是一个移动应用程序,所以我的网页实际上只是帮助构建和测试):

var socket = io('http://localhost:8080/', {
  transports: [ 'websocket' ]
});

You have to use a sticky-session to avoid clients connecting to different servers from the initial handshake. 您必须使用粘性会话来避免客户端从初始握手连接到不同的服务器。 Refer this https://github.com/elad/node-cluster-socket.io 请参阅https://github.com/elad/node-cluster-socket.io

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM