laravel 監聽 websocket 簡單粗暴的方法


1 Laravel 生成命令行

php artisan make:command SwooleDemo

 
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class SwooleDemo extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'swoole:demo';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '這是關於swoole的一個測試demo';
    private static $server = null;


    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $server = self::getWebSocketServer();
        $server->on('open',[$this,'onOpen']);
        $server->on('message', [$this, 'onMessage']);
        $server->on('close', [$this, 'onClose']);
        $server->on('request', [$this, 'onRequest']);
        $this->line("swoole服務啟動成功 ...");
        $server->start();
    }

    // 獲取服務
    public static function getWebSocketServer()
    {
        if (!(self::$server instanceof \swoole_websocket_server)) {
            self::setWebSocketServer();
        }
        return self::$server;
    }
    // 服務處始設置
    protected static function setWebSocketServer():void
    {
        self::$server = new \swoole_websocket_server("0.0.0.0", 9600);
        self::$server->set([
        'worker_num' => 1,
        'heartbeat_check_interval' => 60, // 60秒檢測一次
        'heartbeat_idle_time' => 121, // 121秒沒活動的
        ]);
    }

    // 打開swoole websocket服務回調代碼
    public function onOpen($server, $request)
    {
        if ($this->checkAccess($server, $request)) {
            self::$server->push($request->fd,"打開swoole服務成功!");
        }
    }
    // 給swoole websocket 發送消息回調代碼
    public function onMessage($server, $frame)
    {
        $server->push($frame->fd, '第幾個用戶給我發送'.$frame->fd);
    }
   
    // websocket 關閉回調代碼
    public function onClose($serv,$fd)
    {
        $this->line("客戶端 {$fd} 關閉");
    }
    // 校驗客戶端連接的合法性,無效的連接不允許連接
    public function checkAccess($server, $request):bool
    {
        $bRes = true;
        if (!isset($request->get) || !isset($request->get['token'])) {
            self::$server->close($request->fd);
            $this->line("接口驗證字段不全");
            $bRes = false;
        } else if ($request->get['token'] !== "123456") {
            $this->line("接口驗證錯誤");
            $bRes = false;
        }
        return $bRes;
    }
    // 啟動websocket服務
    public function start()
    {
        self::$server->start();
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>swoole測試</title>
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"></head>
<body>
  <h1>這是一個測試</h1>
<button onclick="sendMsg()">點擊發送</button>

</body>
  <script>

    var ws; //websocket實例
    var lockReconnect = false; //避免重復連接
    var wsUrl = 'ws://homestead.work:9600?page=home&token=123456';

    function initEventHandle() {
      ws.onclose = function() {
        reconnect(wsUrl);
      };
      ws.onerror = function() {
        reconnect(wsUrl);
      };
      ws.onopen = function() {
        //心跳檢測重置
        heartCheck.reset().start();
      };
      ws.onmessage = function(event) {
        //如果獲取到消息,心跳檢測重置
        //拿到任何消息都說明當前連接是正常的
        var data = JSON.parse(event.data);
        heartCheck.reset().start();
      }
    }
    
    createWebSocket(wsUrl);

        function sendMsg(){
            console.log(1111111);
            ws.send("send by myself");
        }
    /**
     * 創建鏈接
     * @param url
     */
    function createWebSocket(url) {
      try {
        ws = new WebSocket(url);
        initEventHandle();
      } catch(e) {
        reconnect(url);
      }
    }
    function reconnect(url) {
      if (lockReconnect) return;
      lockReconnect = true;
      //沒連接上會一直重連,設置延遲避免請求過多
      setTimeout(function() {
        createWebSocket(url);
        lockReconnect = false;
      },2000);
    }
    //心跳檢測
    var heartCheck = {
      timeout: 60000,
      //60秒
      timeoutObj: null,
      serverTimeoutObj: null,
      reset: function() {
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
      },
      start: function() {
        var self = this;
        this.timeoutObj = setTimeout(function() {
        //這里發送一個心跳,后端收到后,返回一個心跳消息,
        //onmessage拿到返回的心跳就說明連接正常
        ws.send("heartbeat");
        self.serverTimeoutObj = setTimeout(function() { //如果超過一定時間還沒重置,說明后端主動斷開了
          ws.close(); //如果onclose會執行reconnect,我們執行ws.close()就行了.如果直接執行reconnect 會觸發onclose導致重連兩次
        },self.timeout);
      },this.timeout);
    },
    header: function(url) {
      window.location.href = url
    }

  }

</script>

</html>

運行命令開啟端口監聽 php artisan swoole:demo


免責聲明!

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



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