【发布时间】:2017-10-26 21:18:35
【问题描述】:
假设有 3 个应用程序实例,应用程序一端接受 Web 套接字连接,另一端作为消费者连接到 RabbitMq。
每次创建新的 Web 套接字连接时,socket 会保存在 JS 对象中并映射到 customerId,当应用程序即将将协议从 HTTP 切换到 WS 时,可从初始 HTTP 握手请求中获得。
const socketStore = {}
io.on('connect', socket => {
...
socketStore[customerId] = socket
})
在另一端,每条 RabbitMQ 消息中也会包含 customerId,它将用于查找合适的 socket 对象。
onNewMessage = message => {
/**
* Consumer parse the message and take customerId
* and find a socket based on it
*/
socketStore[customerId].emit(...)
}
棘手的部分是如何处理 RabbitMQ 消费者从任何应用程序实例收到带有在 socketStore 中找不到的 customerId 的消息的情况?例如,instance number 1 接收到带有 customerId=10 的 Web 套接字连接,但 instance number 2 收到带有 customerId 的 RabbitMQ 消息。在那种情况下,instance number 2 找不到关联的套接字。
此外,单个客户可以同时使用不同的设备(台式机、移动设备、ipad 等)登录,因为在我看来 socketStore(其中customerId 是一个键)应该有一个或每个设备更多的套接字对象,例如:
const socketStore = {
'10': [socket, socket, ..., socket]
}
【问题讨论】:
-
您应该将该地图存储在 redis 或其他快速的内存存储中(使用将“同步”每个参与者的单个实例。
-
如果您的所有实例都订阅所有消息怎么办?使架构更简单。如果在套接字存储中找不到客户 ID,实例将什么也不做。
标签: javascript websocket socket.io rabbitmq