WebSocket原理詳解(二)

WebSocket原理詳解(一)-CSDN博客

目錄

1.WebSocket協議的幀數據詳解

1.1.幀結構

1.2.生成數據幀

2.WebSocket協議控制幀結構詳解

2.1.關閉幀

2.2.ping幀

2.3.pong幀

3.WebSocket心跳機制


1.WebSocket協議的幀數據詳解

1.1.幀結構

????????WebSocket客戶端與服務器通信的最小單位是幀(frame),一條完整消息是由一個或多個幀組成的。數據交互時,發送方會將消息切割為多個幀發送給接收方,接收方接收到消息幀后會重新組裝為完整的消息。

????????當WebSocket接收方接收到一個數據幀時會根據FIN(數據幀中的一個標識,用來判斷當前幀是否當前消息的最后一幀)的值來判斷是否已經接收到消息的最后一個數據幀。當接收到消息的最后一幀時,即可對消息進行處理。

WebSocket 幀由多個字段組成,各字段按順序排列,這些字段共同構成了幀的頭部和可選的負載數據。幀的基本結構如下:

字段長度(字節)描述
FIN1 位表示該幀是否為消息的最后一幀。1 表示是最后一幀,0 表示還有后續幀。
RSV1 - RSV3各 1 位保留位,默認值為 0。如果要使用,需要在握手階段進行協商。
Opcode4 位定義幀的操作類型,如文本幀、二進制幀、關閉幀等。
Mask1 位表示負載數據是否經過掩碼處理。客戶端發送的幀必須進行掩碼處理。
Payload length7 位、7 + 16 位或 7 + 64 位表示負載數據的長度。如果值在 0 - 125 之間,直接使用 7 位表示;如果是 126,則后續 2 個字節表示長度;如果是 127,則后續 8 個字節表示長度。
Masking - key0 或 4 字節如果?Mask?位為 1,則存在 4 字節的掩碼密鑰,用于對負載數據進行掩碼處理。

各字段詳細解釋

1. FIN 字段

  • 作用:用來指示當前幀是否為一個消息的最后一幀。在發送大消息時,消息可能會被拆分成多個幀,FIN?位可以幫助接收方判斷消息是否完整。
  • 取值
    • 1:表示這是消息的最后一幀。
    • 0:表示還有后續幀。

2. RSV1 - RSV3 字段

  • 作用:這三個保留位主要是為未來擴展 WebSocket 協議預留的。目前默認值都為 0,如果要使用這些位,需要在握手階段進行協商。
  • 取值:通常為 0。

3. Opcode 字段

  • 作用:定義了幀的操作類型,接收方根據?Opcode?的值來決定如何處理接收到的幀。
  • 常見取值及含義
    • 0x0:表示延續幀,用于繼續之前未完成的消息。
    • 0x1:表示文本幀,負載數據為 UTF - 8 編碼的文本。
    • 0x2:表示二進制幀,負載數據為二進制數據。
    • 0x3-0x7:保留幀,留作未來非控制幀擴展使用
    • 0x8:表示關閉幀,用于關閉 WebSocket 連接。
    • 0x9:表示心跳檢測的 ping 幀。
    • 0xA:表示心跳檢測的 pong 幀,是對 ping 幀的響應。
    • 0xB-0xF:保留幀, 留作未來控制幀擴展使用

4. Mask 字段

  • 作用:指示負載數據是否經過掩碼處理。為了提高安全性,客戶端發送的幀必須將負載數據進行掩碼處理,服務器發送的幀不需要進行掩碼處理。
  • 取值
    • 1:表示負載數據經過掩碼處理。
    • 0:表示負載數據未經過掩碼處理。

5. Payload length 字段

  • 作用:表示負載數據的長度。由于負載數據長度可能不同,該字段采用了可變長度的編碼方式。
  • 取值及編碼方式
    • 如果值在 0 - 125 之間,直接使用 7 位表示負載數據的長度。
    • 如果值為 126,則后續 2 個字節(16 位)表示負載數據的長度。
    • 如果值為 127,則后續 8 個字節(64 位)表示負載數據的長度。

6. Masking - key 字段

  • 作用:如果?Mask?位為 1,該字段存在,且長度為 4 字節。它是一個隨機生成的掩碼密鑰,用于對負載數據進行掩碼處理和解掩碼處理。
  • 掩碼處理和解掩碼處理:假設?P?是原始的負載數據,M?是掩碼密鑰,C?是經過掩碼處理后的數據,則?C[i] = P[i] ^ M[i % 4],接收方可以使用相同的掩碼密鑰和異或運算對?C?進行解掩碼得到?P

7. Payload data 字段

  • 作用:實際傳輸的數據,可以是文本、二進制數據等,具體取決于?Opcode?的值。

示例

假設客戶端要發送一個簡單的文本消息 "Hello",以下是一個簡化的幀結構分析:

  • FIN:由于這是消息的唯一一幀,FIN?為 1。
  • RSV1 - RSV3:默認值為 0。
  • Opcode:消息是文本,Opcode?為 0x1。
  • Mask:客戶端發送的幀需要掩碼處理,Mask?為 1。
  • Payload length:消息長度為 5 字節,小于 126,直接用 7 位表示,值為 5。
  • Masking - key:隨機生成 4 字節的掩碼密鑰,例如?0x12345678
  • Payload data:將 "Hello" 進行掩碼處理后的數據。

1.2.生成數據幀

????????從服務器發往客戶端的數據也是同樣的數據幀,但是從服務器發送到客戶端的數據幀不需要掩碼的。我們自己需要去生成數據幀,解析數據幀的時候我們需要分片。

消息分片:

????????有時候數據需要分成多個數據包發送,需要使用到分片,也就是說多個數據幀來傳輸一個數據。比如將大數據分成多個數據包傳輸,分片的目的是允許發送未知長度的消息。這樣做的好處是:

  • 大數據的傳輸可以分片傳輸,不用考慮到數據大小導致的長度標志位不夠的情況
  • 和http的chunk一樣,可以邊生成數據邊傳遞消息,可以提高傳輸效率。

????????如果大數據不能被碎片化,那么發送端就必須將數據整個載入內存緩沖之中,然后進行計算長度等操作并發送。但是有了碎片化機制,服務器就可以選取適用的內存緩沖長度,然后當緩沖滿了之后就發送一個消息碎片。

分片規則:

  • 如果一個消息不分片的話,那么該消息只有一幀(FIN為1,opcode非0);
  • 如果一個消息分片的話,它的構成是由
    • 1個起始幀:FIN為0,opcode非0
    • 然后若干幀:FIN為0,opcode為0
    • 1個結束幀:FIN為1,opcode為0

注意:

  • 當前已經定義的控制幀包括 0x8(close)、0x9(Ping)、0xA(Pong)。控制幀可以出現在分片消息中間,但是控制幀不允許分片,控制幀是通過它的opcode的最高有效位是1去確定的。
  • 組成消息的所有幀都是相同的數據類型,在第一幀中的opcode中指明。組成消息的碎片類型必須是文本,二進制,或者其他的保留類型。

2.WebSocket協議控制幀結構詳解

????????目前,控制幀的操作碼定義了0x08(關閉幀)、0x09(Ping幀)、0x0A(Pong幀)。0x0B-0x0F是為那些將來可能定義而目前尚未定義的控制幀預留的。

????????控制幀用于WebSocket協議交換狀態信息,控制幀可以插在消息片段之間。

注意:所有的控制幀的負載長度務必不大于125字節,并且禁止對控制幀進行分片處理。

2.1.關閉幀

????????關閉幀的操作碼Opcode是0x08。

????????關閉幀可能包含數據部分(應用數據幀),該部分表明了關閉的原因,例如:端點關閉、端點接收幀過大或端點收到的幀不符合預期。

  • 如果有數據部分,則數據的前兩個字節必須是一個無符號整數(網絡字節序),該無符號整數表示了一個狀態碼,具體定義哪些關閉碼將在后面的文章中介紹。
  • 在無符號整數后面,可能還有一個UTF-8編碼的數據,表示關閉原因,關閉原因由開發者自行定義(可選),并無規范。關閉原因并不一定是對人可讀的,但會對調試或傳遞相關信息起到一定的作用。由于數據不能保證人類可讀,所以客戶端一定不能將其顯示給用戶(會在關閉事件onclose中)

????????客戶端發送給服務器的關閉幀必須掩碼處理。應用程序在發送了一個關閉幀后,禁止再發送任何數據(此時處于CLOSING狀態)。

????????如果端點(客戶端或服務器)收到了一個關閉幀,并且之前沒有發送過關閉幀,則端點必須發送一個關閉幀作為響應。(當端點發送一個關閉幀回應時,通常會顯示它收到的狀態碼)。當端點可以發送關閉響應時應盡快發送關閉響應。一個端點可以延遲發送響應直到它的當前消息發送完畢(例如,已經發送了大多數的消息片段,則端點可能會在發送關閉響應幀前先將剩下的消息幀發送出去)。但不能保證對方在已經發送了關閉幀后還能夠繼續處理這些數據。

????????在雙方都已發送并接收了關閉幀后,端點需要斷掉WebSocket連接并且必須關閉底層的TCP連接。服務器必須立即切斷底層TCP連接,客戶端最好等待服務器斷開連接,但也可以在發送并接收了關閉幀后任何時候斷開連接,例如在一段時間內服務器仍沒有斷開TCP連接。

????????如果服務器和客戶端同時發送了關閉幀,兩端都會接收關閉幀,并且都需要斷開TCP連接。

關閉幀示例

假設客戶端要發送一個關閉幀,狀態碼為 1000(正常關閉),沒有額外的關閉原因。其幀結構如下:

  • FIN:1
  • RSV1 - RSV3:0 0 0
  • Opcode:0x8
  • Mask:1(客戶端發送)
  • Payload length:2(狀態碼占 2 字節)
  • Masking - key:隨機生成的 4 字節密鑰
  • Payload data:狀態碼 1000(2 字節)

2.2.ping幀

????????Ping幀的操作碼為0x09。

????????Ping幀可以包含應用數據。

????????一旦接到了一個Ping幀,端點必須返回一個Pong幀作為響應,除非它收到了一個關閉幀。它應在可以發送時盡快發送Pong幀響應。

????????端點可以在連接建立后一直到連接關閉前任何時候發送Ping幀。

ping 幀示例

客戶端發送一個 ping 幀,包含自定義的心跳信息 "HEARTBEAT"。其幀結構如下:

  • FIN:1
  • RSV1 - RSV3:0 0 0
  • Opcode:0x9
  • Mask:1(客戶端發送)
  • Payload length:9("HEARTBEAT" 長度為 9)
  • Masking - key:隨機生成的 4 字節密鑰
  • Payload data:經過掩碼處理的 "HEARTBEAT"

2.3.pong幀

????????Pong幀的操作碼為0x0A。

????????Pong幀必須與Ping幀擁有相同的應用數據部分。

????????如果端點收到了多個Ping幀,但還沒來的及全部回應,可以只回應最后一個Ping幀。

????????Pong幀可以在未收到Ping幀時就被發送,用作單向心跳包。

????????對未被請求的Pong幀(對方主動發送的Pong幀)進行回應是不需要的。

3.WebSocket心跳機制

????????心跳機制的核心是客戶端和服務器之間定期發送和接收特定的心跳消息。一般而言,客戶端和服務器中的一方會定期發送心跳消息(如 ping 幀),另一方收到后則立即回復相應的響應消息(如 pong 幀)。若在規定時間內未收到響應,就判定連接出現問題,進而進行重連或其他處理。

????????WebSocket 協議本身定義了 ping 幀和 pong 幀用于心跳檢測。

  • ping 幀:由客戶端或服務器發送,用于主動檢測對方的連接狀態。
  • pong 幀:是對 ping 幀的響應,當一方收到 ping 幀后,必須盡快發送一個 pong 幀,且 pong 幀的負載數據應與 ping 幀的負載數據相同。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/74199.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/74199.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/74199.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 進階 面經級

會用數據庫,找大廠工作是遠遠不夠的。 本人2025美團暑期AI面試好幾個MySQL場景問題不會答,已臟面評。遂在此整理學習! 文章目錄 美團AI面1.數據庫分片sharding的概念,它有什么優勢和挑戰?優勢Sharding 挑戰 2. 分庫分表的常見策…

基于單片機的智能奶茶機(論文 +源碼)

1總體架構設計 本課題為基于單片機的智能奶茶機設計,其系統架構上設計如圖2.1所示,整個系統包括了DS18B20溫度傳感器、繼電器模塊、LCD液晶、蜂鳴器、按鍵、STC89C52單片機等器件,在功能上用戶可以通過按鍵鍵控制選擇甜度和添加物以及設置溫度…

Hue:一個大數據查詢工具

Hue(Hadoop User Experience)是一個用于大數據平臺、數據庫以及數據倉庫查詢的開源工具,旨在通過 Web 界面簡化用戶與 Hadoop 生態系統以及各種數據存儲的交互。 Hue 支持的數據源包括數據庫(Apache Hive、Apache Impala、MySQL、…

并發多線程八股

并發多線程 1.Java里面的線程和操作系統的線程一樣嗎?2.Java的線程安全在三個方面體現:3.保證數據一致性的方案4.線程創建的方式1)Thread類2)Runnable接口3)Callable接口和FutureTask4)線程池(e…

VBA數據庫解決方案第二十講:SQL在VBA中幾種常見的表達方式

《VBA數據庫解決方案》教程(版權10090845)是我推出的第二套教程,目前已經是第二版修訂了。這套教程定位于中級,是學完字典后的另一個專題講解。數據庫是數據處理的利器,教程中詳細介紹了利用ADO連接ACCDB和EXCEL的方法…

大語言模型智體的綜述:方法論、應用和挑戰(下)

25年3月來自北京大學、UIC、廣東大亞灣大學、中科院計算機網絡信息中心、新加坡南陽理工、UCLA、西雅圖華盛頓大學、北京外經貿大學、喬治亞理工和騰訊優圖的論文“Large Language Model Agent: A Survey on Methodology, Applications and Challenges”。 智體時代已經到來&a…

《STL 六大組件之容器篇:簡單了解 list》

目錄 一、list 簡介二、list 的常用接口1. 構造函數(constructor )2. 迭代器(iterator)3. 容量、修改和訪問(capacity 、modify and access) 一、list 簡介 簡單來說,list 就是數據結構初階中學…

nmslib 是一個 超快、適用于高維向量的最近鄰搜索庫,基于 HNSW 算法,被廣泛用于 語義搜索、推薦系統、人臉識別等任務

nmslib 是什么? nmslib(Non-Metric Space Library)是一個 高效的最近鄰搜索(ANN, Approximate Nearest Neighbor Search) 庫,專門用于 高維向量搜索,適用于 文本、圖像、語音等嵌入向量 的相似…

前端流式輸出實現詳解:從原理到實踐

前端流式輸出實現詳解:從原理到實踐 前言一、流式輸出核心原理1.1 什么是流式輸出?1.2 技術優勢對比1.3 關鍵技術支撐 二、原生JavaScript實現方案2.1 使用Fetch API流式處理關鍵點解析: 2.2 處理SSE(Server-Sent Events&#xff…

【STM32】最后一刷-江科大Flash閃存-學習筆記

FLASH簡介 STM32F1系列的FLASH包含程序存儲器、系統存儲器和選項字節三個部分,通過閃存存儲器接口(外設)可以對程序存儲器和選項字節進行擦除和編程,(系統存儲器用于存儲原廠寫入的BootLoader程序,用于串口…

梯度(Gradient)與步長(Step Size)

梯度(Gradient)與步長(Step Size) 梯度與步長是優化算法(如梯度下降法)的核心概念。以下是它們的詳細解釋: 梯度(Gradient) ?定義 梯度是一個向量,表示多元…

freecad二開 xmlrpc接口api qtgui

FreeCAD.ConfigGet("UserAppData") 文件夾下創建mod文件夾 mod文件夾底下創建插件文件夾my_server: freecad_server.py: from xmlrpc.server import SimpleXMLRPCServer import FreeCADGui import FreeCADimport queue from PySide2.QtCore import QTi…

鴻蒙NEXT開發日志工具類(ArkTs)

import hilog from ohos.hilog; import { JSON } from kit.ArkTS; import { BusinessError } from kit.BasicServicesKit; import { StrUtil } from ./StrUtil;/*** 日志工具類* author: 鴻蒙布道師* since: 2024/03/31*/ export class LogUtil {private static logSize: numbe…

《Linux運維總結:基于銀河麒麟V10+ARM64架構CPU源碼編譯部署單實例redis7.2.6》

總結:整理不易,如果對你有幫助,可否點贊關注一下? 更多詳細內容請參考:《Linux運維篇:Linux系統運維指南》 一、環境信息 環境信息如下: 主機IP 操作系統 Redis版本 CPU架構 192.168.1.111 K…

基于LSTM的文本分類1——模型搭建

源碼 # coding: UTF-8 import torch import torch.nn as nn import torch.nn.functional as F import numpy as npclass Config(object):"""配置參數類,用于存儲模型和訓練的超參數"""def __init__(self, dataset, embedding):self.…

小了 60,500 倍,但更強;AI 的“深度詛咒”

作者:Ignacio de Gregorio 圖片來自 Unsplash 的 Bahnijit Barman 幾周前,我們看到 Anthropic 嘗試訓練 Claude 去通關寶可夢。模型是有點進展,但離真正通關還差得遠。 但現在,一個獨立的小團隊用一個只有一千萬參數的模型通關了…

nextjs使用02

并行路由 同一個頁面,放多個路由,, 目錄前面加,layout中可以當作插槽引入 import React from "react";function layout({children,notifications,user}:{children:React.ReactNode,notifications:React.ReactNode,user:React.Re…

github 無法在shell里鏈接

當我在shell端git push時,我發現總是22 timeout的問題。 我就進行了以下步驟的嘗試并最終得到了解決。 第一步,我先確定我可以curl github,也就是我網絡沒問題 curl -v https://github.com 如果這個時候不超時和報錯,說明網絡…

當前主流的大模型知識庫軟件對比分析

以下是當前主流的大模型知識庫軟件對比分析,涵蓋功能特性、適用場景及優劣勢,結合最新技術動態和行業實踐提供深度選型參考: 一、企業級智能知識庫平臺 1. 阿里云百煉(Model Studio) 核心能力:基于RAG技…

Java的比較器 Comparable 和 Comparator

在 Java 中,Comparable 和 Comparator 是用于對象排序的重要接口。它們提供了不同的排序方式,適用于不同的需求,同時在 Java 底層排序算法中發揮著關鍵作用。本文將從基礎概念、使用方法、排序實現(包括升序、降序)、底…