thinkphp6集成gatewayWorker(workerman)實現實時監聽


環境:基於composer引入包和thinkphp6+https+workerman.

1.composer引入gatewayworker 使用phpstorm更方便(在composer.json中require中添加這些 phpstorm會自動引入) 或者使用命令行 composer require XXX

    "workerman/workerman": "^4.0",
        "workerman/gateway-worker": "^3.0",
        "workerman/gatewayclient": "^3.0",

0.編寫workerman啟動文件 workerman單獨部署的 與你的項目無關 public/workerman.php(這個用來測試workman啟動的-------------------)

<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2019 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

// [ wokerman啟動文件 和整個項目無關聯]
namespace think;

use Workerman\Worker;

require_once __DIR__ . '/../vendor/workerman/workerman/Autoloader.php';
// 創建一個Worker監聽2345端口,使用http協議通訊
$http_worker = new Worker("http://0.0.0.0:2345");

// 啟動4個進程對外提供服務
$http_worker->count = 4;

// 接收到瀏覽器發送的數據時回復hello world給瀏覽器
$http_worker->onMessage = function($connection, $data)
{
    // 向瀏覽器發送hello world
  //  $connection->send('hello world');
};

// 運行worker
Worker::runAll();

2.利用命令創建workerman php think make:command workerman 並編寫文件app/command/Workerman.php

<?php
//declare (strict_types=1);

namespace app\command;

use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use Workerman\Worker;

require_once __DIR__ . '/../../vendor/workerman/workerman/Autoloader.php';

class Workerman extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('workerman')
            ->setDescription('the workerman command');
    }

    protected function execute(Input $input, Output $output)
    {
        $this->startGateWay();

        $this->startBusinessWorker();

        $this->startRegister();

        Worker::runAll();

    }

    private function startBusinessWorker()
    {
        $worker = new BusinessWorker();

        $worker->name = 'BusniessWorker';
        $worker->count = 1;
        $worker->registerAddress = "127.0.0.1:1236";
        $worker->eventHandler = \app\workerman\Events::class;
    }

    private function startGateWay()
    {
        $gateway = new Gateway("websocket://127.0.0.1:2346");
        $gateway->name = 'Gateway';
        $gateway->count = 1;
        $gateway->lanIp = '127.0.0.1';
        $gateway->startPort = 2300;
        $gateway->pingInterval = 30;
        $gateway->pingNotResponseLimit = 0;
        $gateway->pingData = '{"type":"heart"}';
        $gateway->registerAddress = "127.0.0.1:1236";
    }

    private function startRegister()
    {
        new Register('text://127.0.0.1:1236');
    }
}

  

3.定義workerman監聽調用方法 heart心跳檢測 

    public function workerman_message($admin_id = '',$content=''){
        Gateway::$registerAddress = '0.0.0.0:1236';


        // 向任意uid的網站頁面發送數據

        $uid = $admin_id;
        $admin = SystemAdmin::find($admin_id);
        $message = new \stdClass();
        $message->type='send';

        if($uid){
            $message->from=$admin_id??'';
            $message->from_name=$admin['username']??'后台消息';
            $message->from_avatar=$admin['head_img']??'https://www.huixx.cn/upload/20200828/e68c50db7b27c784b13a13b87c8ffc71.png';
            $message->content=$content;
            Gateway::sendToUid($uid, json_encode($message,JSON_UNESCAPED_UNICODE));

        }else{
            $message->from_name='后台提醒';
            $message->from_avatar='https://www.huixx.cn/upload/20200828/e68c50db7b27c784b13a13b87c8ffc71.png';
            $message->content=$content;
            Gateway::sendToAll(json_encode($message,JSON_UNESCAPED_UNICODE));
        }

    }

4.前端開啟websocket監聽 加載html提示框 

        /**
         * 與GatewayWorker建立websocket連接,域名和端口改為你實際的域名端口,
         * 其中端口為Gateway端口,即start_gateway.php指定的端口。
         * start_gateway.php 中需要指定websocket協議,像這樣
         * $gateway = new Gateway(websocket://0.0.0.0:7272);
         */
        Notification.requestPermission();

        let protocol = location.protocol === 'https:'
            ? 'wss://test.huixx.cn/wss/'
            : 'ws://0.0.0.0:2346';

        ws = new WebSocket(protocol);
        console.log('websocket啟動')

     
            // 服務端主動推送消息時會觸發這里的onmessage
            ws.onmessage = function (e) {
                // json數據轉換成js對象
                var data = eval("(" + e.data + ")");
                var type = data.type ? data.type : "";

                switch (type) {
                    case 0:
                        break;
                    case "connect":
                        console.log('連婕socket成功!');
                        /*進行id綁定*/
                        var url = '/workerman/bind';
                        var data_post = {
                            client_id: data.id,
                        };
                        $.post(url, data_post, function (re) {
                            var r = /^[0-9]*$/;
                            if (r.test(re)) {
                                console.log('綁定uid:' + re + "成功");
                            }
                        }, 'json');
                        //查詢未接收消息數 並且放置
                        break;

                    case "heart":
                        console.log('心跳檢測正常');
                        break;

                    /*接受到消息的處理*/
                    case "send":
                        //更新在線聊天按鈕
                        console.log(data);
                        layer.msg(data.content)

                        var domain = 'https://' + document.domain;
                        var icon = '';
                        if (data.from_avatar.indexOf('https') != -1) {
                            icon = data.from_avatar;
                        } else {
                            icon = domain + data.from_avatar;
                        }
                        var notification = new Notification(data.from_name, {
                            body: data.content,
                            icon: data.from_avatar
                        });
                        notification.onclick = function () {
                            window.focus();
                            notification.close();
                        }
                        break;

                    default:
                        console.log(data)
                }
            };

   

        

  其他,因為配置了https 所以要wss然后呢要在nginx中做相關配置 如果是http則無需配置 具體參考文檔:http://doc.workerman.net/faq/secure-websocket-server.html

  

  location /wss {
    proxy_pass http://127.0.0.1:2346;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

  


  注意上述代碼關系到的端口均要在雲服務器開通 在雲上開通。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM