以前咱們已經簡單的瞭解過了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在服務端的簡單介紹了