什么是WebSocket
WebSocket協(xié)議是基于TCP的一種新的網(wǎng)絡(luò)協(xié)議窒典。他實現(xiàn)了瀏覽器與服務(wù)器全雙工通信—允許服務(wù)器主動發(fā)送信息給客戶端。
WebSocket特點
建立在TCP協(xié)議之上
性能開銷小性能高效
客戶端可以與任意服務(wù)器通信
協(xié)議標(biāo)識符號 ws wss
持久化網(wǎng)絡(luò)通信協(xié)議
WebSocket服務(wù)器是建立在Http服務(wù)器之上的長連接服務(wù)器蟆沫,客戶端首先會發(fā)送一個Http的請求與服務(wù)器進(jìn)行握手。握手成功后會觸發(fā)onOpen事件,表示連接已就緒,onOpen函數(shù)中可以得到$request對象缭召,包含了Http握手的相關(guān)信息,如GET參數(shù)逆日、Cookie嵌巷、Http頭信息等。
建立連接后客戶端與服務(wù)器端就可以雙向通信了室抽。
客戶端向服務(wù)器端發(fā)送信息時搪哪,服務(wù)器端觸發(fā)onMessage事件回調(diào)
服務(wù)器端可以調(diào)用$server->push()向某個客戶端(使用$fd標(biāo)識符)發(fā)送消息
服務(wù)器端可以設(shè)置onHandShake事件回調(diào)來手工處理WebSocket握手
swoole_http_server是swoole_server的子類,內(nèi)置了Http的支持
swoole_websocket_server是swoole_http_server的子類坪圾, 內(nèi)置了WebSocket的支持噩死。
創(chuàng)建WebSocket.php
$server = new Swoole\WebSocket\Server("0.0.0.0", 8812);
$server->on('open', function (Swoole\WebSocket\Server $server, $request) {
echo "server: handshake success with fd{$request->fd}\n";
});
$server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
$server->push($frame->fd, "this is server");
});
$server->on('close', function ($ser, $fd) {
echo "client {$fd} closed\n";
});
$server->start();
onRequest回調(diào)
WebSocket\Server 繼承自 Http\Server
設(shè)置了onRequest回調(diào),WebSocket\Server也可以同時作為http服務(wù)器
未設(shè)置onRequest回調(diào)神年,WebSocket\Server收到http請求后會返回http 400錯誤頁面
如果想通過接收http觸發(fā)所有websocket的推送,需要注意作用域的問題行嗤,面向過程請使用global對WebSocket\Server進(jìn)行引用已日,面向?qū)ο罂梢园裌ebSocket\Server設(shè)置成一個成員屬性
創(chuàng)建ws_client.html
var wsServer = 'ws://127.0.0.1:8812';
var websocket = new WebSocket(wsServer);
websocket.onopen = function (evt) {
websocket.send("hello websocket world");
console.log("Connected to WebSocket server.");
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
測試
1、通過httpserver來開啟:分別執(zhí)行swoole-http服務(wù)栅屏、websocket服務(wù)文件啟動服務(wù)飘千,瀏覽器訪問http://127.0.0.1:8811/ws_client.html,注意這里請求的是8811端口栈雳,即httpserver中配置的端口护奈,在控制臺中查看效果。同時可在瀏覽器開啟多個會話哥纫,查看多個連接效果霉旗。
2、通過websocket-server來開啟加載:
在websocket-server中添加配置
$server->set(
[
'enable_static_handler' => true,
'document_root' => '/opt/work/htdocs/swoole_mooc/demo/data',
]
);
此時關(guān)閉http-server蛀骇、websocket-server厌秒,并重啟websocket-server,不再重啟http-server擅憔,使用8812端口在瀏覽器訪問http://127.0.0.1:8812/ws_client.html鸵闪,同樣成功。