• Swoole-WebSocket服务端主动推送消息


    Swoole-WebSocket服务端主动推送消息

    标签(空格分隔): websocket swoole php

    swoole-request.jpg

    WebSocket服务器代码

    <?php
    namespace swoolewebsocket;
    
    class WebSocketServer
    {
    
        var $server;
    
        public function __construct()
        {
            $this->server = new SwooleWebSocketServer("0.0.0.0", 9991);
            print "WebSocketServer: 0.0.0.0, 9991" . PHP_EOL;
            $this->server->set([
                'task_worker_num' =>4
            ]);
            $this->server->on('open', [$this, 'open']);
            $this->server->on('message', [$this, 'message']);
            $this->server->on('task', [$this, 'task']);
            $this->server->on('finish', [$this, 'finish']);
            $this->server->on('request', [$this, 'request']);
            $this->server->on('close', [$this, 'close']);
            $this->server->start();
        }
    
    
        /**
         * $request 是一个 HTTP 请求对象,包含了客户端发来的握手请求信息
         * onOpen 事件函数中可以调用 push 向客户端发送数据或者调用 close 关闭连接
         * onOpen 事件回调是可选的
         * @param SwooleWebSocketServer $server
         * @param SwooleHttpRequest $request
         */
        public function open($server, $request)
        {
            $fd = $request->fd;
            echo "server: handshake success with fd{$fd}" . PHP_EOL;
        }
    
    
        /**
         * $frame 是 SwooleWebSocketFrame 对象,包含了客户端发来的数据帧信息
         * onMessage 回调必须被设置,未设置服务器将无法启动
         * 客户端发送的 ping 帧不会触发 onMessage,底层会自动回复 pong 包,也可设置 open_websocket_ping_frame 参数手动处理
         * @param SwooleWebSocketServer $server
         * @param SwooleWebSocketFrame $frame
         */
        public function message($server, $frame)
        {
            $data = json_decode($frame->data, true);
            var_dump("---收到消息----fd:{$frame->fd}");
            var_dump($data);
            $server->task($data);
    
            // 保持连接 心跳检测
            if ($data['type'] == 'ping') {
                $server->push($frame->fd, json_encode(['type' => 'ping', 'data' => 'tong']));
            }
        }
    
        /**
         * @param SwooleWebSocketServer $server
         * @param $fd
         */
        public function close($server, $fd)
        {
            echo "fd:{$fd} close" . PHP_EOL;
        }
    
    
        /**
         * @param SwooleServer $server
         * @param int $taskId
         * @param int $srcWorkerId
         * @param mixed $data
         */
        public function task($server, $taskId, $srcWorkerId, $data)
        {
            echo "正在处理任务----taskId:{$taskId}" . PHP_EOL;
            sleep("3");
            $server->finish("ok");
        }
    
    
        /**
         * @param SwooleServer $server
         * @param int $task_id
         * @param mixed $data
         */
        public function finish($server, $taskId, $data)
        {
            echo "任务处理成功-----taskId:{$taskId}";
        }
    
    
        public function request(SwooleHttpRequest $request, SwooleHttpResponse $response)
        {
            echo "服务端主动推送消息......" . PHP_EOL;
            if ($request->server['path_info'] == "/websocket/") {
                foreach ($this->server->connections as $fd) {
                    if ($this->server->isEstablished($fd)) {
                        $this->server->push($fd, json_encode(['type' => 3, 'data' => '系统消息推送' . mt_rand(1000, 9999)]));
                    }
                }
            }
        }
    }
    
    new WebSocketServer();
    

    客户端(JS)

    <script>
    document.addEventListener("DOMContentLoaded", function() {
        var wsServer = 'ws://web.test.com/wss';
        var websocket = new WebSocket(wsServer);
        websocket.onopen = function (evt) {
            console.log("已连接上服务器");
        };
    
        //每隔5秒钟发送一次心跳,避免websocket连接因超时而自动断开
        window.setInterval(function(){
            var ping = {"type":"ping"};
            websocket.send(JSON.stringify(ping));
        },10000);
    
        websocket.onclose = function (evt) {
            console.log("连接已关闭");
        };
    
        websocket.onmessage = function (evt) {
            data = eval("("+evt.data+")");
            if (data.type == "ping") {
                return;
            }
            console.log('接受信息: ' + data.data);
        };
    });
    

    客户端(php)

    $result = curl_get("http://0.0.0.0:9991/websocket/");
  • 相关阅读:
    luogu P1382 楼房
    luogu P1908 逆序对
    5.28 模拟赛
    POJ 2991 Crane
    残(矩阵快速幂)
    AC日记——拍照 洛谷 P3410
    AC日记——[CQOI2014]危桥 洛谷 P3163
    AC日记——【模板】二分图匹配 洛谷 P3386
    AC日记——[ZJOI2009]假期的宿舍 cogs 1333
    AC日记——城市 洛谷 P1401
  • 原文地址:https://www.cnblogs.com/yanweifeng/p/15351844.html
Copyright © 2020-2023  润新知