• Swoole 中使用 WebSocket 异步服务器、WebSocket 协程服务器


    WebSocket 异步风格服务器

    WebSocketServer 继承自 HttpServer,所以 HttpServer 提供的所有 API 和配置项都可以使用。

    # ws_server.php
    
    class WebSocket
    {
        public $server;
    
        public function __construct()
        {
            // 创建websocket服务器对象,监听0.0.0.0:9502端口
            $this->server = new SwooleWebSocketServer("0.0.0.0", 9502);
    
            // 设置服务器运行参数
            $this->server->set(array(
                'daemonize'     => 1,  // 作为守护进程运行,需同时设置log_file
                'log_file'      => '/www/logs/swoole.log',  // 指定标准输出和错误日志文件
            ));
            
            // 监听WebSocket连接打开事件
            $this->server->on('open', function ($ws, $request) {
                var_dump($request->fd, $request->get, $request->server);
                $ws->push($request->fd, "hello, welcome
    ");
            });
    
            // 监听WebSocket消息事件
            $this->server->on('message', function ($ws, $frame) {
                echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}
    ";
                $ws->push($frame->fd, "server: {$frame->data}");
            });
    
            // 监听WebSocket连接关闭事件
            $this->server->on('close', function ($ws, $fd) {
                echo "client {$fd} is closed
    ";
            });
    
            // 通过 HTTP 请求向所有用户推送消息
            $this->server->on('request', function ($request, $response) {
                foreach ($this->server->connections as $fd) {
                    // 检查连接是否为有效的 WebSocket 客户端连接,避免push失败
                    if ($this->server->isEstablished($fd)) {
                        $this->server->push($fd, $request->get['message']);
                    }
                }
            });
    
            $this->server->start();
        }
    }
    
    // 启动 WebSocket 服务器
    new WebSocket();
    

    运行并测试 WebSocket 异步风格服务器

    # 如果程序已经运行,先结束进程
    kill -9 11591
    
    # 在 cli 命令行环境运行服务端
    php ws_server.php
    
    # 查看服务器监听的端口
    netstat -an | grep 9502
    

    WebSocket JS客户端

    # index.js
    
    var wsServer = 'ws://127.0.0.1:9502';
    var websocket = new WebSocket(wsServer);
    websocket.onopen = function (evt) {
        console.log("Connected to WebSocket server.");
        websocket.send('hello ws!');
    };
    
    websocket.onclose = function (evt) {
        console.log("Disconnected");
    };
    
    websocket.onmessage = function (evt) {
        console.log('Retrieved data from server: ' + evt.data);
    };
    
    websocket.onerror = function (evt, e) {
        console.log('Error occured: ' + evt.data);
    };
    
    

    客户端

    • Chrome/Firefox/ 高版本 IE/Safari 等浏览器内置了 JS 语言的 WebSocket 客户端
    • 微信小程序开发框架内置的 WebSocket 客户端
    • 异步 IOPHP 程序中可以使用 SwooleCoroutineHttp 作为 WebSocket 客户端
    • Apache/PHP-FPM 或其他同步阻塞的 PHP 程序中可以使用 swoole/framework 提供的同步 WebSocket 客户端
    • WebSocket 客户端不能与 WebSocket 服务器通信

    WebSocket 协程风格服务器

    Co
    un(function () {
        $server = new CoHttpServer("127.0.0.1", 9502, false);
    
        // 设置服务器运行参数
        $server->set(array(
            'daemonize'     => 1,  // 作为守护进程运行,需同时设置log_file
            'log_file'      => '/www/logs/swoole.log',  // 指定标准输出和错误日志文件
        ));
    
        $server->handle('/websocket', function ($request, $ws) {
            // 向客户端发送 WebSocket 握手消息
            $ws->upgrade();
            
            // 循环处理消息的接收和发送
            while (true) {
                // 接收 WebSocket 消息帧,会挂起当前协程,等待数据到来时再恢复协程的执行
                $frame = $ws->recv();
                if ($frame === false) {
                    echo "error : " . swoole_last_error() . "
    ";
                    break;
                } else if ($frame == '') {
                    break;
                } else {
                    if ($frame->data == "close") {
                        $ws->close();
                        return;
                    }
                    
                    // 向对端发送数据帧
                    $ws->push("Hello {$frame->data}!");
                    $ws->push("How are you, {$frame->data}?");
                }
            }
        });
    
        $server->handle('/', function ($request, $response) {
            $response->end(<<<HTML
    <h1>Swoole WebSocket Server</h1>
    <script>
    var wsServer = 'ws://127.0.0.1:9502/websocket';
    var websocket = new WebSocket(wsServer);
    websocket.onopen = function (evt) {
        console.log("Connected to WebSocket server.");
        websocket.send('hello');
    };
    
    websocket.onclose = function (evt) {
        console.log("Disconnected");
    };
    
    websocket.onmessage = function (evt) {
        console.log('Retrieved data from server: ' + evt.data);
    };
    
    websocket.onerror = function (evt, e) {
        console.log('Error occured: ' + evt.data);
    };
    </script>
    HTML
            );
        });
    
        $server->start();
    });
    

    WebSocket 协程客户端

    官方建议使用 Saber

  • 相关阅读:
    通讯技术
    (1)sqlserver2017安装
    c# api身份验证和授权
    ()centos7 安装python36
    python 包管理
    ()centos7 安装mysql8.0
    [bzoj1095][ZJOI2007]Hide 捉迷藏 点分树,动态点分治
    bzoj 3544 [ONTAK2010]Creative Accounting 贪心
    BZOJ4300 绝世好题 dp
    bzoj 4295 [PA2015]Hazard 贪心,暴力
  • 原文地址:https://www.cnblogs.com/danhuang/p/13199999.html
Copyright © 2020-2023  润新知