美文网首页
laravel-swoole和websocket入门(二)

laravel-swoole和websocket入门(二)

作者: 小牛_6666 | 来源:发表于2020-06-16 17:32 被阅读0次

    laravel-swoole和websocket入门(一)中,我们已经就 扩展的安装和启动作了介绍, laravel-swoole除了能大幅度的提升系统性能之后,还有一个很大的功能是 websocket长链接,这篇将详细介绍长链接部分。

    1,启动长链接

    • 首先我们要开放端口,比如我们要启动1215端口为长链接端口,那么服务器要先放行1215端口,具体放行的方法各种服务器不一样,就不细说了。
    • 修改 config/swoole_http.php 部分配置
    'server' => [
            //服务地址 用0.0.0.0代替127.0.0.1 具体原因不知,反正127.0.0.1连不上
            'host' => env('SWOOLE_HTTP_HOST', '0.0.0.0'), 
            'port' => env('SWOOLE_HTTP_PORT', '1215'),
    
          //是否后台运行,测试阶段可以不用后台运行,方便查看运行状态 生产的时候后台运行
            'daemonize' => env('SWOOLE_HTTP_DAEMONIZE', false), 
    ]
    
    'websocket' => [
            //这里是 websocket的总开关, true和falsefalse,看着办
            'enabled' => env('SWOOLE_HTTP_WEBSOCKET', true), 
        ],
    
    • 在路由文件里输出下测试 route/websocket.php
    Websocket::on('connect', function ($websocket, Request $request) {
        echo "connect";
        // called while socket on connect
    });
    
    Websocket::on('disconnect', function ($websocket) {
        // called while socket on disconnect
        echo "disconnect";
    });
    

    现在我们启动服务,链接测试一下

    php artisan swoole:http restart

    客户端可以使用这个网站来测试

    微信截图_20200616153724.png

    在控制台我们可以看到连接成功的提示


    微信截图_20200616154928.png

    查看代码

    2,如何接收客户端发送的信息,并在系统中进行业务处理

    建立一个长链接并不难,网上也有很多其他的方法,一个单文件脚本就可以建起长链接,但是我们很难在一个单文件里进行复杂的业务处理。使用 swoole-websocket,我们可以很方便的把长链接发送的数据经过路由转到 Controller,就像处理正常的 http请求一样,处理websocket, laravel里面的大部分功能都可以正常使用,如 Model,Cache等。可以和我们的业务逻辑高度契合。

    • 首先我们约定所有的数据传输都是 json格式,必须包含两个字段event,data。event就类似于请求的 route路由, data是请求的数据
    {
      "event": "login",
      "data": {
        "uid": 1
      }
    }
    

    返回的数据也是类似

    {
      "event": "return",
      "data": "我收到了你的消息{"uid":1}"
    }
    
    

    以下是大概思路,具体还请查看代码

    • 1,创建一个WebsocketHandler类,放在哪都行,我是放在了 app\Swoole
      这个类主要是对 websocket的一个操作类,有三个事件onOpen,onMessage,onClose,我这里只用了 onOpen事件,就是长链接建立链接事件,这里我要返回 fd(客户端的一个编号,后面所有向客户端发信息都需要这个 fd),当然也可以做其他的处理
    public function onOpen($fd, Request $request)
        {
            /**
             * 客户端建立起长链接后,返回客户端fd
             */
            $this->server->push($fd, json_encode(['event' => 'open', 'data' => ['fd' => $fd]]));
            return true;
        }
    
    

    链接建立后客户端会收到信息

    {
        "event": "open",
        "data": {
            "fd": 2
        }
    }
    
    • 2,创建一个Parser类,仍然放在app\Swoole
      这个类主要是对长链接传送的数据进行 encode和 decode,如果不想用 json或者有其他的数据转换可以在这里面
    public function encode(string $event, $data)
        {
            $string = ['event' => $event, 'data' => $data];
            return json_encode($string);
        }
    
    public function decode($frame)
        {
            //这里是解析客户端发来的数据,我们约定所有的传输都是json
            $json = $frame->data;
            $data = json_decode($json, true);
            if (!$data || !isset($data['event'])) {
                return ['event' => 'error', 'data' => $frame->data];
            }
            return ['event' => $data['event'], 'data' => $data['data'] ?? ''];
        }
    
    • 3,创建一条路由,route/websocket.php
    /**
     * 定义一个login路由,指向控制器方法,和http类似
     */
    Websocket::on('login','App\Http\Controllers\Index\LoginController@index');
    
    • 4,修改 config/swoole_websocket.php config/swoole_websocket.php,设置我们刚才自已添加的两个类
    'handler' => \App\Swoole\WebsocketHandler::class,
    'parser' => \App\Swoole\Parser::class,
    
    • 5, 创建控制器方法App\Http\Controllers\Index\LoginController
    public function index(Websocket $websocket, $data)
        {
            /**
             * 这里就可以做业务处理,比如绑定用户和fd等
             */
            $websocket->emit('return', "我收到了你的消息" . json_encode($data));
        }
    

    这里面注入两个变量,一个是 websocket,用来操作 websocket的,比如回复信息,data就是客户端发送的数据

    到此就可以测试了


    微信截图_20200616172054.png

    查看代码

    有问题请留言

    未完待续

    2,在普通http请求中,服务器主动向客户端推送长链接消息

    3,聊天室,群发功能

    4,wss长链接证书配置

    5,长链接的负载均衡问题

    相关文章

      网友评论

          本文标题:laravel-swoole和websocket入门(二)

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