美文网首页
Swoole优雅的实现给在线用户推送websocket广播消息(

Swoole优雅的实现给在线用户推送websocket广播消息(

作者: 骑蚂蚁上高速_jun | 来源:发表于2020-03-22 00:43 被阅读0次

    前期本人写过一篇关于 Swoole两种方案实现总后台给所有在线用户 群发通知
    的文章, 现在研究了一种更好的实现案例。推荐生产环境使用该种方案
    直接上案例:

    use Swoole\Websocket\Server;
    use Swoole\Coroutine as Co;
    use Swoole\Runtime;
    
    $server= new Server("0.0.0.0",20001);
    /**
     * 重点: 开启环境协程化,使所有的客户端协程话
     */
    Runtime::enableCoroutine(SWOOLE_HOOK_ALL | SWOOLE_HOOK_CURL);
    $server->set([
        "worker_num"=>2,
        "enable_coroutine"=>true,// 必须开启协程异步化
    ]);
    
    $server->on("workerStart",function(Server $server,int $workerId){
        $pid=$server->master_pid;
      /**
      * 在子协程中 实现的 redis 订阅端,是异步化的。 并不会影响客户端的连接
      */
        if($workerId ==0){
            Co::create(function()use($server){
                $redis = new Redis();
                $redis->connect("127.0.0.1");
                $redis->setOption(Redis::OPT_READ_TIMEOUT,-1);
                $redis->subscribe(['test'],function(Redis $instance,string $channelName,string $message)use($server){
                    /**
                     * 1. 遍历所有的连接,
                     * 2 . 判断所有的 ws客户端连接
                     * 3. 给客户端发送消息
                     */
                    foreach ($server->connections as $fd){
                        if($server->isEstablished($fd)){
                            $server->push($fd,"send message to client success!");
                        }
                    }
                });
            });
        }
       // 这句话打印的次数与配置中worker_num 是一致的,表示上述redis订阅端并不会影响 worker进程接收请求
        echo "进程{$workerId} 启动\n";
    });
    
    $server->on("request",function(\Swoole\Http\Request $request,\Swoole\Http\Response $response){
        $response->status(201);
        $response->header("content-type","text/html;charset=utf-8");
        $response->end("哈哈".getmypid());
    });
    /**
     * 接收客户端消息触发
     */
    $server->on("message",function(Server $server, \Swoole\Websocket\Frame $frame){
        $fd = $frame->fd;
        $data = $frame->data;
        echo "接收到客户端{$fd} 消息: {$data} \n";
    });
    
    
    $server->start();
    

    相关文章

      网友评论

          本文标题:Swoole优雅的实现给在线用户推送websocket广播消息(

          本文链接:https://www.haomeiwen.com/subject/rrnpyhtx.html