websocket 聊天室中私聊功能,应该就是两个用户的 client_id 之间通信吧。
那频道群聊功能呢?
翻了下别人写的 demo,都是 foreach 遍历该频道的所有 client_id 然后逐个推送,感觉好 low,那如果百人群,千人群,万人群,那服务器岂不是炸锅了,麻烦大佬指点下。
//demo 进程启动向所有客户端连接发送数据
foreach ($room_users as $key => $clientId){
if ($currentSessionId != $clientId){
$this->send($clientId, $msg);
}else{
$this->send($clientId, $msg_my);
}
}
1
firefox12 2019-12-20 12:20:04 +08:00
否则咋整,你要让所有人知道,又不推给所有人,别人怎么知道?写在一个公共队列里,然后让所有人自己来拉?仔细想想这样设计的缺陷在哪里?
|
2
kop1989 2019-12-20 12:22:50 +08:00
微信网页版的实现方式更 low,都不是 websocket,是长轮询。
每个人的网页无时无刻发送一个异步 http 请求到服务器,超时就再发,然后服务器把这个请求线程 hold 住,如果有信息变化,则请求返回特定 flag。网页收到特定 flag,再去调用业务请求来拉取信息。 |
4
binkcn 2020-04-27 18:11:39 +08:00
websocket 的 group 广播消息一般都是这种 foreach 方式。
实际场景里面一般有这几类情况: 1 、显示分拆成聊天组,也就是多个 group,这样每个 group 里面的人不会太多,常见于各类聊天工具的“群”模式。 2 、隐藏式拆分组,比如各种直播平台的弹幕,假定 1w 人同时看一个直播,当有一个人发弹幕的时候,你以为是其他 9999 个人都能收到?不是的…… 实际上这 1w 人会被拆分成 N 个 group,只有那种 vip 用户的加粗弹幕,以及系统广播才是所有人能收到的,这种是先 foreach group,然后继续 foreach clientid 。 你很难看到哪个聊天软件支持万人级别同时聊天,一来负载太大,二来也没有意义(试想一个上万人的群,那个刷屏速度谁看的过来?) |