首頁  >  文章  >  php框架  >  Think-Swoole教程之WebSocket的介紹、事件與資料發送

Think-Swoole教程之WebSocket的介紹、事件與資料發送

藏色散人
藏色散人轉載
2020-10-16 14:33:493314瀏覽

Think-Swoole教程之WebSocket的介紹、事件與資料發送

什麼是WebSocket

WebSocket 協定是基於TCP 的一種新的網路協議,使得客戶端和伺服器之間的資料交換變得更加簡單,允許服務端主動向客戶端推送資料。在 WebSocket API 中,瀏覽器和伺服器只需要完成一次握手,兩者之間就直接可以創建持久性的連接,並進行雙向資料傳輸。

為什麼需要 WebSocket

因為 HTTP 的通訊只能由客戶端發起。

WebSocket有哪些特點

  • #建立在TCP協定之上的

  • ##效能開銷小,通訊高效

  • 客戶端可以與任意的伺服器進行通訊

  • #協定標識:ws、wss

  • 持久化網路通訊協定

WebSocket 使用場景

社群聊天、彈幕、多玩家遊戲、協同編輯、股票基金即時報價、體育實況更新、視訊會議聊天、基於位置的應用、線上教育等需要高即時性的運用場景。

在 WebSocket 之前,傳統方式我們想要做聊天程序,可能會使用 JavaScript 定時器,每隔一秒鐘發送一次 HTTP 請求到伺服器,查詢有沒有新訊息。

有了 WebSocket ,客戶端透過瀏覽器以 HTTP 方式向服務端發送 WebSocket 連線請求,然後伺服器發出回應,這個過程通常稱為「握手」 。瀏覽器和伺服器只需要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道,將協定升級為 WebSocket,有新訊息的話,服務端主動將訊息推送給客戶端。

SocketIO 又是什麼

WebSocket 是HTML5 最新提出的規範,雖然主流瀏覽器都已經支持,但仍然可能有不相容的情況,為了兼容所有瀏覽器,給程式設計師提供一致的程式設計體驗, SocketIO 將WebSocket 、AJAX 和其它的通信方式全部封裝成了統一的通信接口,也就是說,我們在使用SocketIO 時,不用擔心兼容問題,底層會自動選用最佳的通訊方式。因此說,WebSocket 是 SocketIO 的子集,Think-Swoole 中是依照 SocketIO 進行解析傳送到服務端的資料。

在 ThinkPHP 6 中開啟 WebSocket 服務

1、設定檔 config/swoole.php 中「websocket. enable」設定為 true。

2、建立監聽事件,建立WsConnect、WsClose、WsTest(這個可任意命名,和客戶端須對應),在專案根目錄分別輸入如下指令:

php think make:listener WsConnect
php think make:listener WsClose
php think make:listener WsTest

app/ listener 目錄下會產生剛才建立的監聽類別文件,在對應的事件類別中可寫入業務邏輯。我們這裡先印出 $event 這個變數。 Connect 事件中的 $event 是 app\Request 請求對象,Test自訂訊息接收事件的 $event 是客戶端發送過來的訊息。

3、在app/event.php 中的陣列listen 鍵中定義事件監聽類別:

app/event.php
'listen'    => [
        'AppInit'  => [],
        'HttpRun'  => [],
        'HttpEnd'  => [],
        'LogLevel' => [],
        'LogWrite' => [],
        //监听连接,swoole 事件必须以 swoole 开头
        'swoole.websocket.Connect' => [
            app\listener\WsConnect::class
        ],
        //监听关闭
        'swoole.websocket.Close' => [
            \app\listener\WsClose::class
        ],
        //监听 Test 场景
        'swoole.websocket.Test' => [
            \app\listener\WsTest::class
        ],
    ],

swoole.websocket.Connect:客戶端與伺服器建立連線並完成握手事件,即Swoole 中的onOpen 事件。在這裡記錄你自己程式用戶與客戶端的連線ID(fd)等。非必須,建議定義。

swoole.websocket.Close:客戶端連線關閉事件,非必須。

swoole.websocket.Test:自訂的 Test 事件;用於接收客戶端發送的 test 事件的訊息。一個專案中可以定義多個 Test 事件,例如聊天、定位、客服功能事件,則可對應 Test1、Test2、Test3等。

WebSocket 的事件也可以在config/swoole.php 設定檔的「websocket. listen」設定:

'listen' => [
    // 首字母大小写都可以;值应该是字符串非数组
    'connect' => 'app\listener\WsConnect',
    'close'   => 'app\listener\WsClose',
    'test'    => 'app\listener\WsTest'
],

4、專案根目錄開啟服務:php think swoole start 即可,底層會自動判斷目前請求是HTTP 還是WebSocket。

客戶端與服務端建立連線

現在我們做一個 HTML 頁面,透過 HTML5 WebSocket 向我們的伺服器端建立連線。在任意地方新建 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);
    }
    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>

HTML5 WebSocket 有關介紹,可以訪問這裡進行學習。

前端程式碼中var ws = new WebSocket("ws://127.0.0.1:9501/"); 我的伺服器是在本地,swoole.php 設定檔中配置的連接埠號碼是9501,所以存取127.0.0.1:9501,ws 是WebSocket 協議,與HTTP、HTTPS 一樣,它有WS 和WSS 協議。 ws.onmessage 可以接受訊息。

接下來透過瀏覽器存取這個HTML 頁面,並開啟瀏覽器偵錯控制台,可以看到連線成功的字樣,以及服務端列印出來的參數:

Think-Swoole教程之WebSocket的介紹、事件與資料發送

然後我們在剛才創建的HTML 頁面的輸入框中發送訊息,控制台中列印出了我們的訊息:

Think-Swoole教程之WebSocket的介紹、事件與資料發送

Swoole 監聽服務終端機中,也收到了我們發送過來的訊息:

Think-Swoole教程之WebSocket的介紹、事件與資料發送

這是因為我們在app/listener /WsTest 印了$event 變數。

最後說明一下前端頁面中ws.send(JSON.stringify(['test',{to:to,message:message}])); 這段程式碼,JSON.stringify() 的作用是將JavaScript 物件轉換為JSON 字串,to 和message 屬性是我們自訂的,test 是後端定義的Test 事件,這個名稱一定和後端對應。由於think-swoole中是按照SocketIO 進行解析發送過來的數據,所以你發送的數據應該是“['事件名', 真正要發送的數據]” 的字符串形式:第一個參數的test 就是對應伺服器端的Test 事件,用來區分更多場景的即時通訊邏輯業務;第二個參數才是你真正發送的數據,可以是字串、數據、對象,伺服器端$event 參數取得的就是它。

以上是Think-Swoole教程之WebSocket的介紹、事件與資料發送的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:阿dai哥。如有侵權,請聯絡admin@php.cn刪除