多端口下,后台发布赛况的时候,怎么才能让后台推送的消息只发到赛况里呢。聊天室的消息只发给聊天室呢

来源:10-1 本章节介绍

不吃鱼的喵儿

2019-01-08

丝袜老师,请问一下,当我的ws.php服务监听了8821时,

 CONST HOST = "0.0.0.0";
    CONST PORT = 8811;
    CONST CHART_PORT = 8812;

    public $ws = null;
    public function __construct() {

    $this->ws = new swoole_websocket_server(self::HOST, self::PORT);
    $this->ws ->listen(self::HOST, self::CHART_PORT, SWOOLE_SOCK_TCP);

我通过后台发布直播信息时,客户端确收到了两次信息,图片
图片描述通过后台发布的直播信息,客户端,却有两次输出,然后,赛况数据就不能实时刷新了。
后台推送代码如下

  $clients = Predis::getInstance()->sMembers('live_game_key');

        foreach ($clients as $fd){
            $serv->push($fd,json_encode($data));
     
        }

这里的$ser->push推送,消息推送到聊天室,也推送到赛况里了,
请问老师,后台发布赛况的时候,怎么才能让后台推送的消息只发到赛况里呢。聊天室的消息只发给聊天室呢

写回答

2回答

我心依然_Song

2020-03-22

发布的赛况信息是通过异步任务执行发送的,异步任务中是从redis里面取出之前存的客户端的fd。所以可以在onopen中这样写:

public function onOpen($ws, $request) {
if ($ws->getClientInfo($request->fd)['server_port'] == self::PORT) {
\app\common\services\Redis::getInstance()->sadd('live_game_fd', $request->fd);
}
echo "js-client:".$request->fd.PHP_EOL;
}


如果是发布赛况信息的端口就存入redis,如果是聊天的则不存入。

异步任务:

//赛况
public function livePush($data, $serv=null) {
    $client = Redis::getInstance()->sMembers('live_game_fd');
    foreach($client as $cfd) {
        $serv->push($cfd, json_encode($data));
    }
}
//聊天信息
public function chatPush($data, $serv=null) {
    foreach($serv->ports[1]->connections as $fd) {
        $serv->push($fd, json_encode($data));
    }
}


0
2
慕虎4477515
还有别的办法吗
2022-08-14
共2条回复

不吃鱼的喵儿

提问者

2019-01-08

刚刚,我用了个笨方法,通过判断:

websocket.onmessage = function(evt) {

    if(JSON.parse(evt.data).user){
        pushs(evt.data);
    }

    console.log("ws-server-return-data:" + evt.data);
}

onmessage里的值,然后拼接数据,想问下老师,有没有php代码处理的方式呢,就是后台提交只让他执行live.js,打印数据只让它打印live.js里,聊天只让他打印chart.js里

0
2
慕虎4477515
还有别的办法吗?
2022-08-14
共2条回复

Swoole入门到实战打造高性能赛事直播平台

swoole创始人推荐,借助Swoole打造高性能直播平台

2228 学习 · 1062 问题

查看课程