【问题标题】:How io.adapter works under the hood?io.adapter 如何在幕后工作?
【发布时间】:2014-11-18 19:48:58
【问题描述】:
我正在开发由 node.js + express + socket.io 提供支持的 1-1 聊天室应用程序。
我在关注文章:Socket.IO - Rooms and Namespaces
在文章中他们演示了如何使用模块socket.io-redis 启动io.adapter:
var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
两个问题:
- 在文档中,他们提到了另外两个参数:
pubClient 和 subClient。我应该提供它们吗?有什么区别?
- io.adapter 的行为如何?例如,如果用户 A 连接到服务器 A,而用户 B 是服务器 B,并且他们想互相“交谈”。引擎盖下发生了什么?
谢谢。
【问题讨论】:
标签:
node.js
express
websocket
socket.io
cluster-computing
【解决方案1】:
您不需要传递自己的 pubClient/subClient。如果您传递主机/端口,它们将为您创建。但是,如果您想自己创建它们,出于任何原因(例如,您想调整重新连接超时),您可以创建这 2 个客户端并将其传递给适配器。
-
适配器在内部广播所有发射。因此,它为您提供了集群功能。例如。假设您有聊天应用程序,并且在负载均衡器后面有 3 个 node.js 服务器(因此它们共享单个 URL)。我们还假设 6 个不同的浏览器连接到负载均衡器 URL,它们被路由到 3 个单独的 node.js 进程,每个 node.js 服务器有 2 个用户。如果客户端 #1 发送消息,node.js #1 将执行类似io.to('chatroom').emit('msg from user #1') 的操作。如果没有适配器,服务器 #1 的两个用户都将收到发射,但不会收到其余 4 个用户。但是,如果您使用适配器,剩余的 node.js #2 和 node.js #3 将收到发出已完成的信息,并将向其客户端发出相同的发出 - 所有 6 个用户都将收到初始消息。
李>
【解决方案2】:
我一直在为同样的问题苦苦挣扎,但找到了一个似乎对我有用的答案,至少在我最初的测试阶段是这样。
我有一个使用 express、cluster、socket.io、socket.io-redis 和 NOT sticky-sessions 运行 8 个实例的集群应用程序 -> 因为使用 sticky 似乎会导致大量奇怪的错误。
我认为 socket.io 文档中缺少的是:
io.adapter(redis({ host: 'localhost', port: 6379 })); 仅支持 web sockets(至少它不支持长轮询),因此客户端需要指定 websockets 是唯一可用的传输。一旦我这样做了,我就可以开始了。所以在 client 方面,我将 {transports:['websockets']} 添加到套接字构造函数中......所以而不是这个......
var socketio = io.connect( window.location.origin );
使用这个
var socketio = io.connect( window.location.origin , {transports:['websocket']} );
我无法从 socket.io 中找到更多文档来支持我的理论,但补充一下就可以了。
我将这个无法正常工作的聊天示例分叉并在这里工作:https://github.com/squivo/chat-example-cluster 所以终于有一个在线工作示例:D