您好,登錄后才能下訂單哦!
這篇文章主要介紹了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('think\swoole\Websocket'); // 單例 //獲取當前發送消息客戶端的 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('連接成功'); } ws.onmessage = function(data){ console.log(data.data); } ws.onclose = function(){ console.log('連接斷開'); } function send() { var message = document.getElementById('message').value; var to = document.getElementById('to').value; console.log("準備給" + to + "發送數據:" + message); ws.send(JSON.stringify(['test',{ to:to, message:message }])); //發送的數據必須是 ['test',數據] 這種格式 } </script> </body> </html>
瀏覽器打開多個標簽,來模擬多個客戶端連接,均訪問 test.html 文件,控制臺將會打印出每個客戶端的 fd ,如下圖我們打開三個標簽進行訪問:
也就是說,服務端發送過來的消息,都會被 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('think\swoole\Websocket'); // 單例 //獲取當前發送消息客戶端的 fd var_dump($ws -> getSender()); //發送給指定 fd 的客戶端,包括發送者自己 $ws -> to(intval($event['to'])) -> emit('testcallback',$event['message']); } }
$ws -> to()是設置收件人 fd 或聊天室名,如果發送給多個人可以數組設置多個,例如 [1,2,3],fd 須為整型。$ws -> emit() 是發送消息方法,第一個參數是事件名稱,用于多場景,可任意定義,就如上一片文章中客戶端給服務端發送消息的 Test 一樣。第二個參數是發送的內容,可以是字符串、數組,單獨調用不設置收件人的話,就是發送消息給當前 fd 。
重啟 Think-Swoole 服務,分別打開三個客戶端進行連接,fd 分別為 1、2、3,現在,現在,我們用 fd 為 1 的客戶端,發消息給 fd 為 2 的客戶端:
發送后,可見只有 fd 為 1、2 的客戶端能收到消息(也就是說消息發出者自身也會收到消息),而 fd 為 3 的客戶端卻沒有收到消息:
發送后,可見只有 fd 為 1、2 的客戶端能收到消息(也就是說消息發出者自身也會收到消息),而 fd 為 3 的客戶端卻沒有收到消息:
發送廣播消息
廣播消息就是發送一條消息給所有客戶端,但是不包括自己。
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('testcallback',$event['message']); } }
$ws -> broadcast() 方法就是發送廣播消息。
但是如果想自己也收到廣播消息,那就需要增加一條 $ws -> to($ws -> getSender()) -> emit('testcallback',$event['message']); 即可。
模擬客戶端給另一個客戶端發消息
假設我當前 fd 為 1,但是我要模擬 用 fd 為 2 的客戶端給 fd 為 3 的客戶端發送消息,只需設置發送者 fd 和接收者兩個 fd 即可:
$ws -> setSender(2) -> to(3) -> emit('testcallback',$event['message']);
經測試,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('think\swoole\Manager'); $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 原生方法怎么調用”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。