ws出現之前的http連接
在ws出現以前,http都是
客戶端發起-服務器回應的模式,全靠客戶端主動交流,服務器完全是被動等待請求,回覆數據。如果需要服務器主動推送信息給客戶端(例如現在手機上的應用提醒),只能靠客戶端主動pulling 或 long pulling不間斷的請求服務器獲取數據,並且http是無狀態的,每次請求數據的時候都需要帶認證信息,還需要每次進行tcp連接,非常消耗資源。關於 pulling 和 long pulling 的介紹,點擊查看
WebSocket協議
先來看一個ws的握手請求
GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: Upgrade
Upgrade: websocket
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: VR+OReqwhymoQ21dBtoIMQ==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
ShellCopy
跟http類似,不過需要帶上Connection和Upgrade域,告訴服務器,我要升級為ws連接,
各個域介紹是:
* 必須是有效的http request格式
* HTTP request method 必須是GET,協議應不小於1.1 如: Get / HTTP/1.1
* 必須包括Upgrade頭域,並且其值為websocket
* 必須包括Connection頭域,並且其值為Upgrade
* 必須包括Sec-WebSocket-Key頭域,其值採用base64編碼的隨機16字節長的字符序列
* 如果請求來自瀏覽器客戶端,還必須包括Origin頭域 。 該頭域用於防止未授權的跨域腳本攻擊,服務器可以從Origin決定是否接受該WebSocket連接
* 必須包括Sec-webSocket-Version頭域,當前值必須是13
* 可能包括Sec-WebSocket-Protocol,表示client(應用程序)支持的協議列表,server選擇一個或者沒有可接受的協議響應之
* 可能包括Sec-WebSocket-Extensions, 協議擴展, 某類協議可能支持多個擴展,通過它可以實現協議增強
* 可能包括任意其他域,如cookie
服務器端響應如下:
HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: Y+Te7S7wQJC0FwXumEdGbv9/Mek=
ShellCopy
說明:
* 必須包括Upgrade頭域,並且其值為websocket
* 必須包括Connection頭域,並且其值為Upgrade
* 必須包括Sec-WebSocket-Accept頭域,其值是將請求包Sec-WebSocket-Key的值,與258EAFA5-E914-47DA-95CA-C5AB0DC85B11這個字符串進行拼接,然後對拼接後的字符串進行sha-1運算,再進行base64編碼,就是Sec-WebSocket-Accept的值
* 應答包中冒號後面有一個空格
* 最後需要兩個空行作為應答包結束
然後就建立通信了,後續就是ws的雙向通信了,http就不用了。
ws和http一樣,都是默認監聽80和443端口
閱讀更多 cpp軟件架構獅 的文章