首頁 > php框架 > ThinkPHP > 主體

Think-Swoole之WebSocket訊息、廣播以及 Swoole 原生方法調用

發布: 2020-10-19 14:52:28
轉載
3448 人瀏覽過

Think-Swoole 教程之WebSocket 訊息、廣播以及Swoole 原生方法呼叫

什麼是客戶端的fd

fd 是在Swoole 中客戶端的唯一識別符,fd 是複用的,當連線關閉後fd 會被新進入的連線複用,正在維持的TCP 連線fd 不會被重複使用。

取得目前客戶端的fd

app/listener/WsConnect.php

<?php
declare (strict_types = 1);
namespace app\listener;
use \think\swoole\Websocket;
class WsTest
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event,Websocket $ws)
{
//        $ws = app(&#39;think\swoole\Websocket&#39;); // 单例
        //获取当前发送消息客户端的 fd
        var_dump($ws -> getSender());
    }
}
登入後複製

test.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
消息:<input type="text" id="message">
接收者:<input type="text" id="to">
<button onclick="send()">发送</button>
<script>
    var ws = new WebSocket("ws://127.0.0.1:9501/");
    ws.onopen = function(){
        console.log(&#39;连接成功&#39;);
    }
    ws.onmessage = function(data){
        console.log(data.data);
    }
    ws.onclose = function(){
        console.log(&#39;连接断开&#39;);
    }
    function send()
{
        var message = document.getElementById(&#39;message&#39;).value;
        var to = document.getElementById(&#39;to&#39;).value;
        console.log("准备给" + to + "发送数据:" + message);
        ws.send(JSON.stringify([&#39;test&#39;,{
            to:to,
            message:message
        }])); //发送的数据必须是 [&#39;test&#39;,数据] 这种格式
    }
</script>
</body>
</html>
登入後複製

瀏覽器打開多個標籤,來模擬多個客戶端連接,均訪問test.html 文件,控制台將會列印每個客戶端的fd ,如下圖我們打開三個標籤進行訪問:

Think-Swoole之WebSocket訊息、廣播以及 Swoole 原生方法調用

也就是說,服務端發送過來的訊息,都會被HTML 中的ws.onmessage 接收到。

給指定fd 的客戶端發送訊息(單發、群發)

app/listener/WsTest.php

<?php
declare (strict_types = 1);
namespace app\listener;
use \think\swoole\Websocket;
class WsTest
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event,Websocket $ws)
{
//        $ws = app(&#39;think\swoole\Websocket&#39;); // 单例
        //获取当前发送消息客户端的 fd
        var_dump($ws -> getSender());
        //发送给指定 fd 的客户端,包括发送者自己
        $ws -> to(intval($event[&#39;to&#39;])) -> emit(&#39;testcallback&#39;,$event[&#39;message&#39;]);
    }
}
登入後複製

$ws -> to()是設定收件者fd 或聊天室名,如果傳送給多個人可以陣列設定多個,例如[1,2,3],fd 須為整數。 $ws -> emit() 是傳送訊息方法,第一個參數是事件名稱,用於多場景,可任意定義,就如上一片文章中客戶端給服務端傳送訊息的 Test 一樣。第二個參數是發送的內容,可以是字串、數組,單獨呼叫不設定收件人的話,就是發送訊息給目前 fd 。

重啟Think-Swoole 服務,分別打開三個客戶端進行連接,fd 分別為1、2、3,現在,現在,我們用fd 為1 的客戶端,發送訊息給fd 為2 的客戶端:

Think-Swoole之WebSocket訊息、廣播以及 Swoole 原生方法調用

發送後,可見只有fd 為1、2 的客戶端能收到訊息(也就是說訊息發出者本身也會收到訊息),而fd 為3 的客戶端卻沒有收到訊息:

Think-Swoole之WebSocket訊息、廣播以及 Swoole 原生方法調用

發送後,可見只有fd 為1、2 的客戶端能收到訊息(也就是說訊息發出者本身也會收到訊息),而fd 為3 的客戶端卻沒有收到訊息:

Think-Swoole之WebSocket訊息、廣播以及 Swoole 原生方法調用

發送廣播訊息

廣播訊息就是發送一條訊息給所有客戶端,但是不包括自己。

app/listener/WsConnect.php

<?php
declare (strict_types = 1);
namespace app\listener;
use \think\swoole\Websocket;
class WsTest
{
    /**
     * 事件监听处理
     *
     * @return mixed
     */
    public function handle($event,Websocket $ws)
{
        //获取当前发送消息客户端的 fd
        var_dump($ws -> getSender());
        //发送广播消息
        $ws -> broadcast() -> emit(&#39;testcallback&#39;,$event[&#39;message&#39;]);
    }
}
登入後複製

$ws -> broadcast() 方法就是發送廣播訊息。

但如果想自己也收到廣播訊息,那就需要增加一條$ws -> to($ws -> getSender()) -> emit('testcallback',$event[' message']); 即可。

模擬客戶端給另一個客戶端發送訊息

假設我目前fd 為1,但是我要模擬用fd 為2 的客戶端給fd 為3 的客戶端發送訊息,只要設定發送者fd 和接收者兩個fd 即可:

$ws -> setSender(2) -> to(3) -> emit(&#39;testcallback&#39;,$event[&#39;message&#39;]);
登入後複製

經測試,1 沒有收到訊息,2 和3 都收到了。

取得 Swoole\WebSocket\Server

假設我們現在需要一個功能,判斷一個客戶端是否為有效客戶端,也就是是否與服務端握手成功。 Think-Swoole 擴充功能中沒有這個功能,但是查閱 Swoole 官方文檔,有個 isEstablished 函數可以完成我們需要的功能,那麼怎麼透過 Think-Swoole 拿到原生 Swoole 函數呢,答案就是取得 Swoole\WebSocket\Server 這個類別。有兩種方式:

1、app('swoole.server');

2、app('think\swoole\Manager') -> getServer();

實例化後,就可以呼叫Swoole 原生方法了,如:

$manager = app(&#39;think\swoole\Manager&#39;);
$manager -> getServer() -> isEstablished(2);
登入後複製

附:\think\Swoole\Websocket類別物件方法:

  • broadcast 設定進行廣播訊息傳送

  • isBroadcast 判斷目前是否為廣播模式

  • to 設定收件者fd 或聊天室名稱(可以陣列設定多個)

  • getTo 取得收件者fd 或聊天室名稱

  • #join 目前用戶端加入到指定聊天室(可以多個)

  • leave 當前客戶端離開指定聊天室(可以多個)

  • #emit 訊息發送

  • close 關閉目前連線

  • getSender 取得目前客戶端id(即fd)

  • setSender 設定寄件者的fd

以上是Think-Swoole之WebSocket訊息、廣播以及 Swoole 原生方法調用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:阿dai哥
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!