webSocket在服務端(PHP)介紹

以前咱們已經簡單的瞭解過了websocket的使用了 php

簡單使用:https://www.wj0511.com/site/detail.html?id=248html

若是須要使用websocket的話,php須要安裝swoole拓展,安裝swoole拓展能夠參考react

windows下安裝swoole拓展:https://www.wj0511.com/site/detail.html?id=246linux

linux下安裝swoole拓展:https://www.wj0511.com/site/detail.html?id=247web

這裏我來詳細的說明下websocket在服務端所須要使用到的方法及屬性算法

一:建立websocket服務器對象windows

在使用websocket以前首先須要建立一個websocket服務器對象數組

$server = new \swoole_websocket_server($host, $port);

參數說明:瀏覽器

$host:websocket須要監聽的IP,0.0.0.0 表示監聽全部IP地址服務器

$port:websocket須要監聽的端口號

根據如上如:

$server = new \swoole_websocket_server('0.0.0.0', '8888');

如上代碼表示建立一個websocket服務器對象並監聽0.0.0.0:8888

二:設置運行參數

建立websocket服務器對象後,咱們能夠設置websocket運行時的各項參數,這時候使用到set方法

$server->set(array $setting);

參數說明:

$server:建立websocket服務器對象返回的對象

$setting:websocket運行各項參數,$setting是一個數組參數

常見的運行參數有:

1:事件處理線程的數量(reactor_num)

'reactor_num' => 2, //經過此參數來調節主進程內事件處理線程的數量,以充分利用多核。默認會啓用CPU核數相同的數量。通常設置爲CPU核數的1-4倍

2:設置啓動的Worker進程數(worker_num)

'worker_num' => 4, //若是業務代碼是全異步非阻塞時,這裏設置爲CPU的1-4倍最合理,若是業務代碼爲同步阻塞,須要根據請求響應時間和系統負載來調整

3:設置worker進程的最大任務數(max_request)

'max_request' => 50, //此參數表示worker進程在處理完n次請求後結束運行。並從新建立一個worker進程。此選項用來防止worker進程內存溢出

4:設置最大最大容許的鏈接數(max_connection)

'max_connection' => 1000, //此參數用來設置Server最大容許維持多少個TCP鏈接。超過此數量後,新進入的鏈接將被拒絕

5:數據包分配模式(dispatch_mode)

'dispatch_mode' => 1, //1平均分配,2按FD取模固定分配,3搶佔式分配,默認爲取模(dispatch=2)

6:當dispatch_mode參數設置爲1和3時,這時候系統會默認關閉onConnect/onClose事件,這時候若是你須要onConnect/onClose事件,這時候你須要設置enable_unsafe_event爲true

'enable\_unsafe\_event' => true,

7:日誌文件路徑(log_file)

'log_file' => '/data/log/swoole.log', // 指定swoole錯誤日誌文件地址,默認錯誤日誌會打印到頁面上

8:設置websocket錯誤日誌打印等級(log_level),範圍是0-5

'log_level' => 1, //低於log_level設置的日誌信息不會拋出

9:進程的PID存儲文件地址(pid_file)

'pid_file' => '/data/log/server.pid',

10:啓動TCP-Keepalive死鏈接檢測(open_tcp_keepalive)

'open\_tcp\_keepalive' => 1

11:指定秒中若是沒有數據請,對此鏈接進行檢測(tcp_keepidle)

'tcp_keepidle' => 5,

12:超過指定探測次數,關閉此鏈接(tcp_keepcount)

'tcp_keepcount' => 5,

13:設置探測的間隔事件,單位爲秒(tcp_keepinterval)

'tcp_keepinterval' => 3

14:心跳檢測機制

(1)heartbeat_check_interval

'heartbeat_check_interval' => 5, //心跳檢測,此選項表示每隔多久輪循一次,單位爲秒

(2)heartbeat_idle_time

'heartbeat_idle_time' => 15, //心跳檢測,鏈接最大容許空閒的時間

15:守護進程化(daemonize)

'daemonize' => 1, //正常狀況下執行websocket腳本時,會在命令行顯示運行過程,當此參數設置爲1時,這時候websocket腳本將轉入後臺做爲守護進程運行

如上就是websocket一些經常使用的運行參數,使用set方法設置運行參數簡單實例以下

$server->set([  
    'max_request' => 50,  
]);

若是你不想要本身進行設置運行參數的話,能夠不適用set方法,這時候系統會使用默認的運行參數

三:註冊websocket事件的回調函數

在websocket中咱們可使用on方法來註冊指定事件的回調函數

$server->on(string $event, mixed $callback);

參數說明:

$server:建立websocket服務器對象返回的對象

$event:須要註冊的事件名稱,此參數須要將事件名稱前面的on字符去除

$callback:回調的PHP函數,能夠是函數名的字符串,類靜態方法,對象方法數組,匿名函數

常見的事件有:

1:onStart:websocket啓動後事件,onStart回調中,僅容許echo、打印Log、修改進程名稱。不得執行其餘操做

如:

$server->on('start', function($server) {  
echo 'server 啓動';  
echo "\n";  
echo 'websocket進程ID爲' . $server->master_pid;  
});

2:onHandShake:WebSocket創建鏈接後進行握手事件,WebSocket服務器已經內置了握手事件,若是用戶但願本身進行握手處理,能夠設置onHandShake事件回調函數

這裏注意,若是你設置了握手事件的話,這時候你就不會再觸發onOpen事件,這時候你就須要手動去觸發onOpen事件

如:

$server->on('handshake', function($request, $response) use ($server) {  
echo '握手成功';  
defaultHandshake($request, $response);  
//手動調用onOpen事件  
$server->defer(function() use ($server, $request) {  
            onOpen($server, $request);  
    });  
});  
//默認的握手處理  
function defaultHandshake($request, $response) {  
// websocket握手鍊接算法驗證  
        $secWebSocketKey = $request->header['sec-websocket-key'];  
        $patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';  
        if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {  
            $response->end();  
            return false;  
        }  
        $key = base64_encode(sha1($request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));  
        $headers = [  
            'Upgrade' => 'websocket',  
            'Connection' => 'Upgrade',  
            'Sec-WebSocket-Accept' => $key,  
            'Sec-WebSocket-Version' => '13',  
        ];  
        if (isset($request->header['sec-websocket-protocol'])) {  
            $headers['Sec-WebSocket-Protocol'] = $request->header['sec-websocket-protocol'];  
        }  
        foreach ($headers as $key => $val) {  
            $response->header($key, $val);  
        }  
        $response->status(101);  
        $response->end();  
}

3:onOpen:當WebSocket客戶端與服務器創建鏈接並完成握手後會回調此函數

如:

$server->on('open', function ($server, $request) {  
echo 'server 鏈接成功';  
});

若是你設置了握手的話,能夠這樣寫:

$server->on('open', function ($server, $request) {  
onOpen($server, $request);  
});  
function onOpen($server, $request) {  
echo 'server 鏈接成功';  
}

4:onMessage:當服務器收到來自客戶端的數據幀時會回調此函數

$server->on('message', function ($server, $frame) {  
    echo "客戶端信息爲" . $frame->data;  
});

5:onRequest:若是設置了onRequest回調,WebSocket也能夠同時做爲http服務器,及當直接在瀏覽器訪問時,onRqeust事件會觸發,若是不設置的話,收到http請求後會返回http 400錯誤頁面

$server->on('request', function ($request, $response) {  
   echo 'server 路由響應'  
});

6:onClose:webscoket客戶端關閉鏈接後觸發

//監聽WebSocket鏈接關閉事件  
$server->on('close', function ($server, $fd) {  
    echo "客戶端進程" . $fd . '關閉';  
});

7:onShutdown:在websocket服務正常關閉時觸發

$server->on('shutdown', function ($server) {  
    echo 'websocket服務端關閉';  
});

如上就是在websocket中常見的事件

四:啓動websocket服務器

$server->start();

當咱們設置好websocket的運行參數和事件回調以後執行如上方法,這時候咱們的websocket服務器就啓動了

五:向客戶端發送消息

在websocket中使用push方法項客戶端發送消息

$server->push($fd, $data);

參數說明:

$fd:客戶端鏈接的ID

$data:要發送的數據內容

六:在websocket中常見的屬性和方法

1:server對象能夠獲取的屬性值和方法

(1):獲websocket全部的運行參數

$server->setting

(2):獲取websocket的主服務進程ID

$server->master_pid

(3):獲取全部的客戶端鏈接ID

[1]

$server->getClientList(0, 10) //參數1表示騎士的客戶端鏈接ID,參數2表示每頁顯示的條數

[2]

foreach($server->connections as $fd)  
{  
echo $fd;  
}

這裏推薦使用$server->connections獲取客戶端鏈接

(4):判斷指定客戶端鏈接ID是否存在

$server->exist($fd)

(5)判斷指定客戶端鏈接ID是否爲已完成握手的WebSocket客戶端鏈接

$server->isEstablished($fd)

(7):咱們能夠主動將指定客戶端鏈接關閉

$server->close($fd);//關閉指定客戶端鏈接

2:request對象能夠獲取的屬性值和方法

(1):獲取當前鏈接的客戶端鏈接ID

$request->fd

(2):獲取客戶端請求傳遞的參數

$request->get

如客戶端地址爲ws://127.0.0.1:8888?id=2時上面獲取的方法返回爲:

[  
    'id' => 2  
]

(3)獲取相關的服務器信息

咱們能夠獲取到客戶端請求的路由

$request->server['request_uri']

如客戶端地址爲ws://127.0.0.1:8888/test時上面獲取的方法返回爲 /test

(4):獲取客戶端的請求頭信息

$request->header

當咱們在客戶端實例化websocket增長第二個參數時如

var wsServer = 'ws://127.0.0.1:8888';  
var websocket = new WebSocket(wsServer, 'public');

這時候在服務端咱們就可使用以下方法獲取到public值

$request->header['sec-websocket-protocol']

如上就是websocket在服務端的簡單介紹了

相關文章
相關標籤/搜索