请问我用socket.io-redis可以实现广播,但是怎么实现一对一聊天呢?
发布于 9 年前 作者 330216851 17835 次浏览 最后一次编辑是 8 年前 来自 问答

现在的情况是运行了2个socket.io的聊天程序,使用了socket.io-redis,群聊的消息大家都能看得到,但是现在我想一对一的进行聊天,不知道怎么弄了,希望指导一下。就是A服务器的某一个用户怎么才能向B服务器的某一个用户发送消息呢?

13 回复

socketid 在用户登录分配服务器的时候 先把用户的socketid 注册到 一个 路由表中 发消息的时候 根据socketid 就可以知道 那个用户在哪个服务器上了 然后用过服务器内部的消息机制 可以还用socket 也可以是RPC 通知用户所在的服务器 然后用户所在的服务器 再根据socketid 向指定用户发消息 不知道这样说你明白了没

不明白哦,这个路由表从哪里可以获取到啊?

使用socket.io 的chanel api,可以对让socket 加入不同的频道,然后用io.in(‘chanel’).broadcast,具体查询socekt.io的api就知道了

但是可能在不同的服务器节点上哦?

吹一下: client发送时包含userId, server保存{userId:client},emit send message时按照userId过滤。

请问socket.io-redis如何实现在多个进程里面共享socket,主要想用于向每个room广播事件

怎么样给动态建立的频道发消息呢? 这个频道是用户在网页上手动建立的,不是在代码里写死的

@gloomyzerg 服务器内部的消息机制 这个怎么理解呢

@lik0914 简单的说你可以这样理解 客户端A 客户端B 服务器C 服务器D 每个客户端连接 websocket 或者socket.io 的时候都会有一个socketid

这个socketid 是向这个客户端发送消息的一个凭证 A连接C服务假如socketid 为1 B连接D服务器假如socketid 为2 你可以把这个路由表存起来 可以是数据库 redis memcache 甚至文件 或者变量 总之 找到 A 在C服务器上 id 是1 B在D服务器上 id是2 A向B 发消息 A 只能把消息发送到他连接的服务器上 也就是C 服务器端去查询B 所在的服务器和socketid 找到他在D服务器上 这是 C服务器向D服务器发送消息 有客户A向要发信息给B 服务器C->D 这里就是服务器的内部消息机制 可以是RPC调用 也可以在C和D之间再连理一个socket D服务器收到从C发来的消息后 转发给和他连接的客户B就可以了 这里要用到B的socketid 不知道这样说的明白不明白 这样无论你有多少个 connector服务器来维持连接 都是可以互相转发和广播的 随着用户的增加你可以增加你的connector服务器 也就是上面说的 C和D 来进行扩展 这里和我们平时用快递和邮局差不多 你要给别人发快递 你(客户A)得先把快递(消息)给本城市的快递公司(相当与服务器C) 但本城市快递不能直接送给另外一个城市的人 所以要转运给另一个城市的快递网点(服务器D),可以是陆运也可以空运(这就是内部转发的机制) 再由这个网点送个你向要送的人 (客户B) 想要送的快送的多就得增加更多的网点(也就是增加更多的connector服务器) 其实你可以参考一下 pomelo 这个框架的架构 虽然他是一个游戏服务器框架 但是聊天本质上其实也是一个简单的游戏 架构差不多 只是游戏有更多的逻辑而已 啰嗦了半天也不知道说清楚了没有 希望你能看懂吧

@gloomyzerg 非常感谢,意思大概明白了 还有两个问题, 第一,socket.io-redis只能解决类似房间聊天室的广播吗 第二,服务器转发机制,除了rpc调用,就是,发送消息时A服务器的用户到B服务器的用户, A服务器端应该是作为客户端与B服务器建立连接发送通知消息,B服务器收到消息进行转发。

@lik0914 第一 这个我没有用过不太清楚 看介绍 他好像是跨进程共享 socket的一个库 如果是这样 那直接就可以用socketid 向别的服务器上的socket连接发信息 不知道我理解的对不对 没有试过 第二 是这样的 一般我们使用RPC 以为RPC成熟稳定 调用也方便 或者在服务器之间建立socket连接 这里可以用socket 当然也可以用websocket 甚至用消息队列都是可以的 看你怎么方便 只要把消息发过去就行了 你理解的没错 服务器A 就相当于 服务器B的客户端了

@lik0914 之前我做的一个IM 就是用socket.io做的 后来改进之后 直接使用了 pomelo框架做的 如果你要做一个IM产品 推荐试试 pomelo 因为他帮你完成了很多基础工作 基本上 你只要写逻辑就可以了 他的客户端和服务端 都很成熟 目前给出的各平台的SDK 也比较全面

@gloomyzerg 再次感谢, pomelo 这个我在看看,由于业务的原因,下次升级可以考虑pomelo socket.io-redis这个做测试了, 一对一聊天,目前没有通过测试 socket.io 版本 1.2.x 部分代码

socketObj = io.sockets.connected[xxx]; // xxx socket.id 在redis存储
if (socketObj) {
socketObj.emit(eventName, msg);
}
回到顶部