美文网首页程序员
2018年swoole实战2-异步非阻塞投递任务

2018年swoole实战2-异步非阻塞投递任务

作者: 闲睡猫 | 来源:发表于2018-07-27 12:03 被阅读39次

    继上篇 2018年swoole实战1-初识swoole

    项目中,总有一些场景会触发耗时比较长的行为。如:用户更新了文章,触发推送消息给此用户的所有粉丝,如果一个用户有10000个粉丝,用同步阻塞的方式来实现,肯定会被吐槽死,这种场景必须用非阻塞的方式实现,让用户无感知。

    swoole的task任务投递功能可实现异步非阻塞的功能

    以下通过三体人与ETO组织的对话场景来模块此功能:

    废话不多说,亮代码吧...

    服务端

    新建 server.php

    <?php
    
    class WebSocket {
        const HOST = '0.0.0.0';
        const PORT = 8812;
        public $ws = null;
        public function __construct()
        {
            $this->ws = new swoole_websocket_server(self::HOST, self::PORT);
            $this->ws->set(
                [
                    'worker_num' => 2,
                    'task_worker_num' => 2,
                ]
            );
            $this->ws->on('open', [$this, 'onOpen']);
            $this->ws->on('message', [$this, 'onMessage']);
            $this->ws->on('task', [$this, 'onTask']);
            $this->ws->on('finish', [$this, 'onFinish']);
            $this->ws->on('close', [$this, 'onClose']);
    
            $this->ws->start();
        }
    
        /**
         * 监听连接事件
         * @param $ws
         * @param $request
         */
        public function onOpen($ws, $request) {
            echo "收到地球人的连接请求,客户端id:{$request->fd}\n";
        }
    
        /**
         * 监听数据发送事件
         * @param $ws
         * @param $frame
         */
        public function onMessage($ws, $frame) {
            echo "地球人发送的数据:{$frame->data}\n";
            echo "元首:让他们去清理掉面壁者吧...\n";
            // 投递任务
            $data = [
                'task' => '全力加速水滴...\n',
                'fd' => $frame->fd,
            ];
            $time = date('Y-m-d H:i:s', time());
            $ws->push($frame->fd, "清理所有的面壁者, 重点是要不引起任何人注意,无声无息地干掉罗辑!" . $time);
            $ws->task($data); // 投递任务
            $time = date('Y-m-d H:i:s', time());
            $ws->push($frame->fd, "接下来会有水滴协助你们,水滴已经在加速前进了,等水滴到达,我们就无所畏惧了... " . $time);
        }
    
        /**
         * 执行投递的任务
         * @param $server
         * @param $taskId
         * @param $workerId
         * @param $data
         * @return array
         */
        public function onTask($server, $taskId, $workerId, $data) {
            echo $data['task'];
            sleep(5);
            $time = date('Y-m-d H:i:s', time());
            return [
                'fd' => $data['fd'],
                'message' => '水滴加速完成 ' . $time,
            ];
        }
    
        /**
         * 任务完成后的回调
         * @date 2018-07-27
         * @param $server
         * @param $taskId
         * @param $data
         */
        public function onFinish($server, $taskId, $data) { // $data 是 onTask 返回的内容
            $server->push($data['fd'], $data['message']); // 通知客户端,任务已经完成
        }
    
        public function onClose($ws, $fd) {
    
        }
    
    }
    
    $obj = new WebSocket();
    

    客户端

    新建 client.html

    <!doctype html>
    <html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <title>webSocket客户端</title>
    </head>
    <body>
    <h1>swoole异步非阻塞投递任务</h1>
    <script>
        let wsUrl = "ws://127.0.0.1:8812"
        console.log("ETO:向三体世界发送连接请求")
        let webSocket = new WebSocket(wsUrl) // 建立请求连接
    
        webSocket.onopen = function(evt) {
            let message = "主啊,请下达任务,我们必将完成!"
            console.log("ETO:" + message)
            webSocket.send(message); // 发送数据到服务端
        }
    
        webSocket.onmessage = function(evt) { // 接收服务端数据
            let message = String(evt.data)
            console.log("三体人:" + message)
        }
    
        webSocket.onclose = function(evt) {
            console.log("地球与三体的连接已中断")
        }
    
        webSocket.onerror = function(evt, e) {
            let message = String(evt.data)
            console.log("连接出错:" + message)
        }
    </script>
    
    </body>
    </html>
    

    启动服务

    ☁  ws  php server.php
    [2018-07-27 11:50:13 @59805.0]  TRACE   Create swoole_server host=0.0.0.0, port=8812, mode=3, type=1
    
    client

    代码解析

    代码解析

    如果觉得本文对你有所帮助,点个赞,或者赏杯咖啡钱,你的认可对我很重要

    相关文章

      网友评论

        本文标题:2018年swoole实战2-异步非阻塞投递任务

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