workerman 设计一个多房间的聊天室

guoxj

我想在手机app内设计一个群聊的。不知道服务器该如何设计?
请walkor大神回答下。
拜谢

7511 3 0
3个回答

guoxj

我现在是单服务器的情况。
目前考虑的方案是
1.用户进入某聊天室。先向php服务器查询到所有的uid。保存一份列表

当用户进入的时候,用workerman做广播。添加到列表里面
当用户退出,也是workerman广播。然后从列表里面移除。
用户在聊天室内发送信息,即把该消息群发给用户列表里面的用户。

期待@walkor 给到更好方案

  • walkor 2014-08-26

    恩,我的方案和你的应该是一样的,见楼下

walkor

首先下载最新版本的workerman-chat

数据流程及实现步骤:
1、客户端链接到workerman,并进行websocket握手,onConnect代码可以复用workerman-chat的onConnect。onConnect主要工作就是生成一个唯一的uid(实际上是客户端的id,不要用用户的实际uid,因为每个uid可能进入了多个房间,对应多个socket链接),并进行存储(Gateway::storeUid)绑定(Gateway::notifyConnectionSuccess)
2、客户端向服务端发送type为login的json数据,包含了所在房间号$room_id,workerman获得room_id,设置$_SESSION=$room_id,以便下次该客户端发来请求能够直接从$_SESSION获得$room_id。另外还要将该uid(实际上是客户端id)保存到$room_id对应的所有客户端id列表,以便群聊时向这些客户端id发送数据。login的数据中应该还包含用户的user_id,通过这个user_id能够从存储中获得用户名,然后可以将这个用户名也放到$_SESSION中,方便后续请求直接使用
3、当客户端发来type为群聊的消息时,我们能直接从$_SESSION中获取$room_id ,也就能通过$room_id获取所有的客户端id($clientid_array),然后调用Gateway::sendToAll($message, $clientid_array);就向$clientid_array指定的$room_id的所有客户端发送消息了
3、当客户端断开时,注意要将该客户端id从$room_id对应的客户端列表中删掉

注意:
以上重要的一点就是uid是客户端的id,全局唯一标识一个socket链接,以便区分和哪个链接通讯,和用户uid没有直接关系

$_SESSION是和socket绑定的(和用户user_id之间没有直接联系),即每个socket链接会有一个$_SESSION,里面可以存储用户的user_id、user_nick、room_id等信息,以后该socket上的请求可以直接使用$_SESSION的数据,避免了每次读取数据库的开销

多人聊天室的例子已经在计划当中,预计9月份会发出来。

  • 暂无评论
walkor

现在workerman-chat已经支持多房间了,并且支持了私聊、掉线重连、服务端心跳机制
http://github.com/walkor/workerman-chat

  • 暂无评论
年代过于久远,无法发表回答
🔝