websocket與http的區(qū)別?
Http:請求與響應(yīng)的模式立砸,屬于“半雙工”戚长,服務(wù)端只能接收客戶端的請求做出響應(yīng)变隔,無法主動推送數(shù)據(jù)。
websocket:服務(wù)端與客戶端可以隨時給對方發(fā)送信息,屬于“全雙工”,能夠?qū)崿F(xiàn)雙方實時的推送數(shù)據(jù)。
websocket的應(yīng)用場景枣申?
實時推送數(shù)據(jù)(客戶端->服務(wù)端,服務(wù)端->客戶端)
如果沒有websocket看杭,http可以通過長輪詢的方式忠藤,不停地發(fā)送請求去詢問服務(wù)端是否有數(shù)據(jù)可以響應(yīng);但頻繁的請求泊窘,會浪費雙方的資源(CPU熄驼、帶寬等)
項目實踐:
- IM實時通信與多端同步
- 服務(wù)端的定制化推送服務(wù)
websocket通信方式
- 握手,利用 HTTP 協(xié)議實現(xiàn)連接握手烘豹,請求中進行“協(xié)議升級”瓜贾,握手過程中,為了防止誤連接進行一個Sec-WebSocket-Key的認證機制
- 通信携悯,握手成功后祭芦,即可雙工通信
- 心跳,即PING PONG憔鬼,websocket中最好有心跳來維持服務(wù)端與客戶端的長連接通信龟劲,避免被網(wǎng)關(guān)等誤以為無效連接胃夏;可以通過websocket本身協(xié)議配合,或者直接客戶端/服務(wù)端發(fā)起心跳來維持
- 關(guān)閉昌跌,客戶端或服務(wù)端發(fā)送關(guān)閉的信號仰禀,亦或者是一些意外導(dǎo)致強制關(guān)閉
websocket協(xié)議結(jié)構(gòu)
- FIN:消息結(jié)束的標志位;
- RSV:預(yù)留字段蚕愤,為0答恶;
- opcode:操作碼(類型),1表示幀內(nèi)容是純文本萍诱,2表示幀內(nèi)容是二進制數(shù)據(jù)悬嗓,8表示關(guān)閉連接,9表示連接痹7唬活的PING 包竹,10表示連接保活的PONG籍凝;
- MASK:是否使用異或來進行掩碼周瞎;客戶端發(fā)送數(shù)據(jù)必須使用掩碼,而服務(wù)器發(fā)送則必須不使用掩碼
- Payload len:幀內(nèi)容的長度
- Extended payload length:擴展字段
- Masking-key:如果MASK需要掩碼静浴,則為4 個字節(jié)的隨機數(shù)
- Payload Data:幀內(nèi)容
分布式下IM多端同步的實現(xiàn)方案
- websocket多端與后端服務(wù)建立連接
- redis存儲會話信息與會話狀態(tài)
- websocket發(fā)起IM通信
- server接收IM消息堰氓,投遞到mq
- mq進行廣播挤渐,多server訂閱
- 在redis查找存活狀態(tài)的業(yè)務(wù)會話苹享,server除發(fā)起方的websocket,找到當前server有效的websocket進行數(shù)據(jù)的同步
TIP
- 如果沒有心跳浴麻,通過控制臺強制殺客戶端進程得问,或者是斷網(wǎng),會導(dǎo)致服務(wù)端沒辦法知道客戶端已“異橙砻猓”關(guān)閉宫纬;所以需要有“心跳”來維持這個狀態(tài),服務(wù)端主動或被動的維護websocket session的狀態(tài)(調(diào)度清除無用session或心跳回復(fù)后的懶清除)
- 關(guān)于多端同步膏萧,websocket的通信是端對端的漓骚,對于服務(wù)端來說,服務(wù)一般是集群的榛泛,而不是單機的方式蝌蹂,而websocket的session無法序列化,無法通過分布式的組件來存儲并序列化session曹锨,如果需要考慮多端消息同步孤个,只能通過廣播的方式,通知給每一臺服務(wù)端沛简,由各自的服務(wù)端發(fā)起websocket請求齐鲤。
- 關(guān)于websocket最大的長度:沒什么受限斥废,但是用的組件(例如tomcat或者springboot可能會有限制長度)
- 關(guān)于wss:類似https,多個s即多個證書给郊,證書對通信進行加密牡肉,避免通信過程中直接裸露在網(wǎng)絡(luò)上,可在nginx上配置淆九。
- 多端同步過程中荚板,rocketmq是沒辦法同時使用順序方式+廣播模式;原因是廣播是不加鎖的吩屹,順序方式雖然是同一個queue跪另,但如果采用順序方式+分布式模式,那么多個消費者線程會同時處理同個隊列煤搜,也會導(dǎo)致多端同步的數(shù)據(jù)亂序免绿;
解決方案是:分布式模式只限制一個消費者線程(保證消費數(shù)據(jù)也能夠是順序的),只要保證某個會話是順序的的擦盾,那么可以使用線程池并進行線程復(fù)用與分片嘲驾,多線程消費mq訂閱的消息。