1. 程式人生 > >【WebSocket學習】

【WebSocket學習】

概念:WebSocket協議是基於TCP的一種新的網路協議。它實現了瀏覽器與伺服器全雙工(full-duplex)通訊——允許伺服器主動傳送資訊給客戶端。WebSocket通訊協議於2011年被IETF定為標準RFC 6455,並被RFC7936所補充規範。

<?php
class WebSocketServer
{
    public $ws_server;

    CONST PORT = 8090;
    CONST HOST = '0.0.0.0';
    CONST ENABLE_STATIC_HANDLER = TRUE;
    CONST DOCUMENT_ROOT = '/www/wwwroot/swoole';

    
public function __construct() { $this->ws_server = new swoole_websocket_server(self::HOST, self::PORT); $this->ws_server->on('open', function ($ws_server, $request) { $this->onOpen($ws_server, $request); }); $this->ws_server->on('message', function
($ws_server, $frame) { $this->onMessage($ws_server, $frame); }); $this->ws_server->on('close', function ($request, $response) { $this->onClose($request, $response); }); //因為webSocket繼承自 swoole_http_server 所以它也可以作為httpServer $this->ws_server->set([
'document_root' => self::DOCUMENT_ROOT, 'enable_static_handler' => self::ENABLE_STATIC_HANDLER, ]); $this->ws_server->start(); } //監聽webSocket的連線事件 private function onOpen($ws_server, $request) { echo "歡迎客戶端 {$request->fd} 連線本伺服器\n"; } //監聽webSocket的訊息事件 private function onMessage($ws_server, $frame) { //$frame->data,資料內容,可以是文字內容也可以是二進位制資料,可以通過opcode的值來判斷 //$frame->opcode,WebSocket的OpCode型別,可以參考WebSocket協議標準文件 //$frame->finish, 表示資料幀是否完整,一個WebSocket請求可能會分成多個數據幀進行傳送(底層已經實現了自動合併資料幀,現在不用擔心接收到的資料幀不完整) echo "客戶端 {$frame->fd} 說:{$frame->data} (opcode:{$frame->opcode},finish:{$frame->finish})\n"; $ws_server->push($frame->fd, "我是服務端,我已收到您的訊息,您說的是:".$frame->data); } //監聽客戶端關閉連線事件 private function onClose($ws_server, $fd) { echo "客戶端 {$fd} 已關閉連線\n"; } } new WebSocketServer();

啟動服務:

[[email protected] swoole]# php ws_server.php

瀏覽器訪問:

 

websocket和http比較:

HTTP、WebSocket 等應用層協議,都是基於 TCP 協議來傳輸資料的

HTTP:

1,無狀態協議。

2,短連線。(Ajax輪詢方式或Long  poll方式實現“持久連線”狀態)

2,被動型。  客戶端請求->伺服器端響應。服務端不能主動聯絡客戶端,只能有客戶端發起。

WebSocket:

它解決了HTTP的這幾個難題。
如被動性,當伺服器完成協議升級後(HTTP->Websocket),服務端就可以主動推送資訊給客戶端啦。

就變成了這樣,只需要經過一次HTTP請求,就可以做到源源不斷的資訊傳送了。(在程式設計中,這種設計叫做回撥,即:你有資訊了再來通知我,而不是我傻乎乎的每次跑來問你)
這樣的協議解決了同步有延遲,而且還非常消耗資源的這種情況。
那麼為什麼他會解決伺服器上消耗資源的問題呢?
其實我們所用的程式是要經過兩層代理的,即HTTP協議在Nginx等伺服器的解析下,然後再傳送給相應的Handler(PHP等)來處理。
簡單地說,我們有一個非常快速的接線員(Nginx),他負責把問題轉交給相應的客服(Handler)。
本身接線員基本上速度是足夠的,但是每次都卡在客服(Handler)了,老有客服處理速度太慢。,導致客服不夠。
Websocket就解決了這樣一個難題,建立後,可以直接跟接線員建立持久連線,有資訊的時候客服想辦法通知接線員,然後接線員在統一轉交給客戶。
這樣就可以解決客服處理速度過慢的問題了。

同時,在傳統的方式上,要不斷的建立,關閉HTTP協議,由於HTTP是非狀態性的,每次都要重新傳輸identity info(鑑別資訊),來告訴服務端你是誰。
雖然接線員很快速,但是每次都要聽這麼一堆,效率也會有所下降的,同時還得不斷把這些資訊轉交給客服,不但浪費客服的處理時間,而且還會在網路傳輸中消耗過多的流量/時間。
但是Websocket只需要一次HTTP握手,所以說整個通訊過程是建立在一次連線/狀態中,也就避免了HTTP的非狀態性,服務端會一直知道你的資訊,直到你關閉請求,這樣就解決了接線員要反覆解析HTTP協議,還要檢視identity info的資訊。
同時由客戶主動詢問,轉換為伺服器(推送)有資訊的時候就傳送(當然客戶端還是等主動傳送資訊過來的。。),沒有資訊的時候就交給接線員(Nginx),不需要佔用本身速度就慢的客服(Handler)了。

WebSocket 機制

以下簡要介紹一下WebSocket的原理及執行機制。

WebSocket是HTML5下一種新的協議。它實現了瀏覽器與伺服器全雙工通訊,能更好的節省伺服器資源和頻寬並達到實時通訊的目的。它與HTTP一樣通過已建立的TCP連線來傳輸資料,但是它和HTTP最大不同是:

WebSocket是一種雙向通訊協議。在建立連線後,WebSocket伺服器端和客戶端都能主動向對方傳送或接收資料,就像Socket一樣;
WebSocket需要像TCP一樣,先建立連線,連線成功後才能相互通訊。