**WebSocket** 協議是基于TCP的一種新的網絡協議。它實現了瀏覽器與服務器全雙工(full-duplex)通信——允許服務器主動發送信息給客戶端。
## 產生背景
在沒有WebSocket協議之前,在網頁中,實現一個聊天室只能使用 ajax 不斷輪詢,請求服務器是否有數據產生,而這樣的實現方法會出現一系列的問題:
* 如果輪詢時間間隔太短,會導致客戶端和服務端在一個時間段內不斷的進行http tcp的握手/揮手動作和http 請求頭,響應頭的傳輸,大量消耗服務器資源,如果用戶量大的情況,會造成服務器的繁忙以至于宕機
* 客戶端每次只能通過發送http 請求獲得服務器是否有數據返回,且數據的及時性無法保證
WebSocket 只需要一次 http 握手,就可以保持一個長連接,使得服務器可以主動發送消息給客戶端,大大減少了輪詢機制的消耗。
## 實現原理
在實現websocket連線過程中,需要通過瀏覽器發出websocket連線請求,然后服務器發出回應,這個過程通常稱為“握手” 。在 WebSocket API,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。
在此WebSocket 協議中,為我們實現即時服務帶來了兩大好處:
* Header: 互相溝通的Header是很小的-大概只有 2 Bytes
* Server Push: 服務器的推送,服務器不再被動的接收到瀏覽器的請求之后才返回數據,而是在有新數據時就主動推送給瀏覽器。
## 握手協議
客戶端請求:
~~~
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
~~~
服務器回應:
~~~
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
~~~
### 字段說明
* `Connection`必須設置**Upgrade**,表示客戶端希望連接升級。
* `Upgrade`字段必須設置**Websocket**,表示希望升級到 Websocket協議。
* `Sec-WebSocket-Key`是隨機的字符串,服務器端會用這些數據來構造出一個SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一個特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后計算SHA-1摘要,之后進行Base64編碼,將結果做為“Sec-WebSocket-Accept”頭的值,返回給客戶端。如此操作,可以盡量避免普通HTTP請求被誤認為Websocket協議。
* `Sec-WebSocket-Version` 表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均應當棄用。
* `Origin`字段是必須的。如果缺少`origin`字段,WebSocket服務器需要回復HTTP 403 狀態碼(禁止訪問)
* 其他一些定義在HTTP協議中的字段,如Cookie等,也可以在Websocket中使用。
## 優點
* 較小的控制開銷
* 更強的實時性
* 保持連接狀態
* 更好的二進制支持
* 支持擴展
* 更好的壓縮效果
- PHP
- PHP 核心架構
- PHP 生命周期
- PHP-FPM 詳解
- PHP-FPM 配置優化
- PHP 命名空間和自動加載
- PHP 運行模式
- PHP 的 Buffer(緩沖區)
- php.ini 配置文件參數優化
- 常見面試題
- 常用函數
- 幾種排序算法
- PHP - 框架
- Laravel
- Laravel 生命周期
- ThinkPHP
- MySQL
- 常見問題
- MySQL 索引
- 事務
- 鎖機制
- Explain 使用分析
- MySQL 高性能優化規范
- UNION 與 UNION ALL
- MySQL報錯:sql_mode=only_full_group_by
- MySQL 默認的 sql_mode 詳解
- 正則表達式
- Redis
- Redis 知識
- 持久化
- 主從復制、哨兵、集群
- Redis 緩存擊穿、穿透、雪崩
- Redis 分布式鎖
- RedisBloom
- 網絡
- 計算機網絡模型
- TCP
- UDP
- HTTP
- HTTPS
- WebSocket
- 常見幾種網絡攻擊方式
- Nginx
- 狀態碼
- 配置文件
- Nginx 代理+負載均衡
- Nginx 緩存
- Nginx 優化
- Nginx 配置 SSL 證書
- Linux
- 常用命令
- Vim 常用操作命令
- Supervisor 進程管理
- CentOS與Ubuntu系統區別
- Java
- 消息隊列
- 運維
- RAID 磁盤陣列
- 邏輯分區管理 LVM
- 業務
- 標準通信接口設計
- 業務邏輯開發套路的三板斧
- 微信小程序登錄流程
- 7種Web實時消息推送方案
- 用戶簽到
- 用戶注冊-短信驗證碼
- SQLServer 刪除同一天用戶重復簽到
- 軟件研發完整流程
- 前端
- Redux
- 其他
- 百度云盤大文件下載
- 日常報錯記錄
- GIT
- SSL certificate problem: unable to get local issuer certificate
- NPM
- reason: connect ECONNREFUSED 127.0.0.1:31181
- SVN
- SVN客戶端無法連接SVN服務器,主機積極拒絕
- Python
- 基礎
- pyecharts圖表
- 對象
- 數據庫
- PySpark
- 多線程
- 正則
- Hadoop
- 概述
- HDFS