首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Redis Pub/Sub的Socket IO服务器集群

使用Redis Pub/Sub的Socket IO服务器集群
EN

Stack Overflow用户
提问于 2019-04-08 14:31:20
回答 1查看 1.5K关注 0票数 1

因此,首先,我构建了一个获取足球API的微服务,并通过redis的pub/子系统发布了任何更改(如果存在生命核心的话)。

现在,我的服务器(带套接字和路由)将处于群集模式。我已经和socketio-redis安排好了。下面是这个设置的一个片段:

代码语言:javascript
运行
复制
const io = require('socket.io')();
const sRedis = require('socket.io-redis');
const adapter = sRedis({ host: 'localhost', port: 6379 });
const { promisify } = require('util');
const Redis = require('ioredis');
const redis = new Redis();
redis.subscribe('livescore');



io.adapter(adapter);
const ioa = io.of('/').adapter;
ioa.clients = promisify(ioa.clients);
ioa.clientRooms = promisify(ioa.clientRooms);
ioa.remoteJoin = promisify(ioa.remoteJoin);
ioa.remoteLeave = promisify(ioa.remoteLeave);
ioa.allRooms = promisify(ioa.allRooms);

// notice this listener
redis.on('message', (channel, message) => {
    io.emit('livescore', message);
})


io.on('connect', async (socket) => {

    socket.clientRooms = () => ioa.clientRooms(socket.id);
    socket.remoteJoin = (room) => ioa.remoteJoin(socket.id, room);
    socket.remoteLeave = (room) => ioa.remoteLeave(socket.id, room);
    socket.remoteDisconnect = () => ioa.remoteDisconnect(socket.id);


    socket.on('join room', async (id) => {
        await socket.remoteJoin(id);
        socket.emit('join room', `You have joined room ${id}`)
        socket.broadcast.emit('join room', `${socket.id} has joined.`)
    });

    socket.on('leave room', (id) => {
        socket.remoteLeave(id);
    });


})

module.exports = io;

所以,如果我运行这个节点应用程序的单个实例,一切都会很完美。

但是,如果我在集群模式下运行它,假设有4个集群(我使用pm2运行集群模式),则会发生以下情况:

  1. Microservice发布事件。
  2. 每个集群在'livescore‘信道上都有一个订阅。
  3. 每个集群执行io.emit() (对所有客户端)
  4. 客户端几乎同时得到4个相同的事件。

我明白了为什么客户会有4个相同的事件,但我想知道什么是正确的处理方法?

我对解决方案的唯一想法是,我只在一个集群上执行redis子程序,并发布该集群中的所有内容,但我担心对于一个集群来说,这将是太多的工作吗?

有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2019-04-08 14:54:04

可能有多种解决方案来解决这个问题,例如:

使用消息队列而不是pub/sub

根据处理的数量,您可能只需要一个处理消息的节点。在这种情况下,酒吧/潜艇不是你想要的。例如,您可以将消息存储在列表中,并使用LPOP命令获取和删除消息。然后你可以说“第一个抓住它”-这样,只有一个你的服务器将完成这项工作,但基本上是随机的。您还可以使用不同的消息队列,如RabbitMQ、SQS等。

使用Socket.IO发射器发送消息

由于您使用的是socket.io-redis,所以您的消息会被分发到您的节点。有一个项目是socket.io-redis的一部分,叫做socket.io-emitter。它可以用于向所有节点发送消息,而不需要本身。当您在员工微服务(目前将消息写入"livescore“)中实现该功能时,您可以直接向客户端发送消息。但是,如果您需要处理节点应用程序中的消息,这可能不起作用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55575795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档