Heim Web-Frontend js-Tutorial Analyse der WebSocket-Kommunikationsnutzung

Analyse der WebSocket-Kommunikationsnutzung

May 14, 2018 pm 02:32 PM
web websocket 剖析

Dieses Mal werde ich Ihnen eine Analyse der Verwendung der WebSocket-Kommunikation geben. Was sind die Vorsichtsmaßnahmen bei der Analyse der Verwendung der WebSocket-Kommunikation?

Was ist WebSocket?

WebSocket ist ein Standardprotokoll für die bidirektionale Datenübertragung zwischen Client und Server. Aber es hat nichts mit HTTP zu tun, es ist eine unabhängige Implementierung, die auf TCP basiert.

Wenn der Client in der Vergangenheit den Verarbeitungsfortschritt des Servers wissen wollte, musste er ständig Ajax zum Abfragen verwenden, sodass der Browser alle paar Sekunden eine Anfrage an den Server sendete, was zu einem Problem führte großer Druck auf den Server. Eine andere Art der Abfrage ist die Verwendung einer langen Abfrage, die dem Tätigen eines Telefonanrufs ähnelt. Es wird nicht aufgelegt, bis eine Nachricht empfangen wird. Mit anderen Worten: Wenn keine Nachricht vorliegt, wird die Verbindung unterbrochen nicht an den Client zurückgegeben werden, ist die Verbindungsphase immer blockiert.

WebSocket löst diese Probleme von HTTP. Nachdem der Server das Protokoll-Upgrade abgeschlossen hat (HTTP -> WebSocket), kann der Server aktiv Informationen an den Client übertragen und so das durch Abfragen verursachte Problem der Synchronisierungsverzögerung lösen. Da WebSocket nur einen HTTP-Handshake erfordert, kann der Server so lange mit dem Client kommunizieren, bis die Verbindung geschlossen wird. Dadurch entfällt die Notwendigkeit, dass der Server das HTTP-Protokoll wiederholt analysiert, und der Ressourcenaufwand wird reduziert.

Mit der Weiterentwicklung neuer Standards ist WebSocket ausgereifter geworden und verschiedene Mainstream-Browser unterstützen WebSocket besser (nicht kompatibel mit niedrigeren Versionen von IE, IE unter 10). , Sie können einen Blick darauf werfen, wenn Sie Zeit haben.

Bei der Verwendung von WebSocket ist die Front-End-Nutzung relativ standardisiert. js unterstützt das WS-Protokoll. Es fühlt sich ähnlich an wie ein leicht gekapseltes Socket-Protokoll, aber Sie müssen das beibehalten Die bisherigen Verbindungen können nun auf eine standardisiertere Art und Weise hergestellt werden.

Lassen Sie uns anhand des obigen Bildes ausführlich über den Kommunikationsprozess von WebSocket sprechen.

Verbindung herstellen

Kopfzeile der Client-Anfragenachricht

Client-Anfragenachricht:

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13
Nach dem Login kopieren

Unterschiede zum herkömmlichen HTTP-Nachrichten:

Upgrade: websocket
Connection: Upgrade
Nach dem Login kopieren

Diese beiden Zeilen zeigen an, dass das WebSocket-Protokoll initiiert wurde.

Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13
Nach dem Login kopieren

Sec-WebSocket-Key wird zufällig vom Browser generiert und bietet grundlegenden Schutz vor böswilligen oder unbeabsichtigten Verbindungen.

Sec-WebSocket-Version gibt die Version von WebSocket an. Anfangs gab es zu viele WebSocket-Protokolle und verschiedene Hersteller hatten ihre eigenen Protokollversionen, aber jetzt ist dies geklärt. Wenn der Server diese Version nicht unterstützt, muss ein Sec-WebSocket-Versionheader zurückgegeben werden, der die vom Server unterstützte Versionsnummer enthält.

Erstellen Sie ein WebSocket-Objekt:

var ws = new websocket("ws://127.0.0.1:8001");
Nach dem Login kopieren

ws bedeutet die Verwendung des WebSocket-Protokolls, gefolgt von der Adresse und dem Port

Vollständiger Client-Code:

<script type="text/javascript">
 var ws;
 var box = document.getElementById('box');
 function startWS() {
 ws = new WebSocket('ws://127.0.0.1:8001');
 ws.onopen = function (msg) {
 console.log('WebSocket opened!');
 };
 ws.onmessage = function (message) {
 console.log('receive message: ' + message.data);
 box.insertAdjacentHTML('beforeend', '<p>' + message.data + '</p>');
 };
 ws.onerror = function (error) {
 console.log('Error: ' + error.name + error.number);
 };
 ws.onclose = function () {
 console.log('WebSocket closed!');
 };
 }
 function sendMessage() {
 console.log('Sending a message...');
 var text = document.getElementById('text');
 ws.send(text.value);
 }
 window.onbeforeunload = function () {
 ws.onclose = function () {}; // 首先关闭 WebSocket
 ws.close()
 };
</script>
Nach dem Login kopieren

Header der Server-Antwortnachricht

Werfen wir zunächst einen Blick auf die Server-Antwortnachricht:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Nach dem Login kopieren

Erläutern wir es Zeile für Zeile

  • Zunächst zeigt 101 Statuscode an, dass der Server die Anfrage des Clients verstanden hat und den Client über den Upgrade-Nachrichtenheader darüber informiert, dass er ein anderes Protokoll verwenden soll, um die Anfrage abzuschließen >

  • Dann ist Sec-WebSocket-Accept der Sec-WebSocket-Key, der vom Server bestätigt und verschlüsselt wurde

  • Schließlich ist Sec- Das WebSocket-Protokoll ist das Protokoll, das die Endverwendung darstellt.

Berechnungsmethode von Sec-WebSocket-Accept:

  • Spleißen Sie Sec-WebSocket-Key mit 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ;

  • Berechnen Sie den Digest über SHA1 und konvertieren Sie ihn in einen Base64-String.

注意:Sec-WebSocket-Key/Sec-WebSocket-Accept 的换算,只能带来基本的保障,但连接是否安全、数据是否安全、客户端 / 服务端是否合法的 ws 客户端、ws 服务端,其实并没有实际性的保证。

创建主线程,用于实现接受 WebSocket 建立请求:

def create_socket():
 # 启动 Socket 并监听连接
 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 try:
 sock.bind(('127.0.0.1', 8001))
 # 操作系统会在服务器 Socket 被关闭或服务器进程终止后马上释放该服务器的端口,否则操作系统会保留几分钟该端口。
 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 sock.listen(5)
 except Exception as e:
 logging.error(e)
 return
 else:
 logging.info('Server running...')
 # 等待访问
 while True:
 conn, addr = sock.accept() # 此时会进入 waiting 状态
 data = str(conn.recv(1024))
 logging.debug(data)
 header_dict = {}
 header, _ = data.split(r'\r\n\r\n', 1)
 for line in header.split(r'\r\n')[1:]:
 key, val = line.split(': ', 1)
 header_dict[key] = val
 if 'Sec-WebSocket-Key' not in header_dict:
 logging.error('This socket is not websocket, client close.')
 conn.close()
 return
 magic_key = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
 sec_key = header_dict['Sec-WebSocket-Key'] + magic_key
 key = base64.b64encode(hashlib.sha1(bytes(sec_key, encoding='utf-8')).digest())
 key_str = str(key)[2:30]
 logging.debug(key_str)
 response = 'HTTP/1.1 101 Switching Protocols\r\n' \
  'Connection: Upgrade\r\n' \
  'Upgrade: websocket\r\n' \
  'Sec-WebSocket-Accept: {0}\r\n' \
  'WebSocket-Protocol: chat\r\n\r\n'.format(key_str)
 conn.send(bytes(response, encoding='utf-8'))
 logging.debug('Send the handshake data')
 WebSocketThread(conn).start()
Nach dem Login kopieren

进行通信

服务端解析 WebSocket 报文

Server 端接收到 Client 发来的报文需要进行解析

Client 包格式

FIN: 占 1bit

0:不是消息的最后一个分片
1:是消息的最后一个分片

RSV1, RSV2, RSV3:各占 1bit

一般情况下全为 0。当客户端、服务端协商采用 WebSocket 扩展时,这三个标志位可以非
0,且值的含义由扩展进行定义。如果出现非零的值,且并没有采用 WebSocket 扩展,连接出错。

Opcode: 4bit

%x0:表示一个延续帧。当 Opcode 为 0 时,表示本次数据传输采用了数据分片,当前收到的数据帧为其中一个数据分片;
%x1:表示这是一个文本帧(text frame);
%x2:表示这是一个二进制帧(binary frame);
%x3-7:保留的操作代码,用于后续定义的非控制帧;
%x8:表示连接断开;
%x9:表示这是一个心跳请求(ping);
%xA:表示这是一个心跳响应(pong);
%xB-F:保留的操作代码,用于后续定义的控制帧。

Mask: 1bit

表示是否要对数据载荷进行掩码异或操作。
0:否
1:是

Payload length: 7bit or (7 + 16)bit or (7 + 64)bit

表示数据载荷的长度
0~126:数据的长度等于该值;
126:后续 2 个字节代表一个 16 位的无符号整数,该无符号整数的值为数据的长度;
127:后续 8 个字节代表一个 64 位的无符号整数(最高位为 0),该无符号整数的值为数据的长度。

Masking-key: 0 or 4bytes

当 Mask 为 1,则携带了 4 字节的 Masking-key;
当 Mask 为 0,则没有 Masking-key。
掩码算法:按位做循环异或运算,先对该位的索引取模来获得 Masking-key 中对应的值 x,然后对该位与 x 做异或,从而得到真实的 byte 数据。
注意:掩码的作用并不是为了防止数据泄密,而是为了防止早期版本的协议中存在的代理缓存污染攻击(proxy cache poisoning attacks)等问题。

Payload Data: 载荷数据

解析 WebSocket 报文代码如下:

def read_msg(data):
 logging.debug(data)
 msg_len = data[1] & 127 # 数据载荷的长度
 if msg_len == 126:
 mask = data[4:8] # Mask 掩码
 content = data[8:] # 消息内容
 elif msg_len == 127:
 mask = data[10:14]
 content = data[14:]
 else:
 mask = data[2:6]
 content = data[6:]
 raw_str = '' # 解码后的内容
 for i, d in enumerate(content):
 raw_str += chr(d ^ mask[i % 4])
 return raw_str
Nach dem Login kopieren

服务端发送 WebSocket 报文

返回时不携带掩码,所以 Mask 位为 0,再按载荷数据的大小写入长度,最后写入载荷数据。

struct 模块解析

struct.pack(fmt, v1, v2, ...)
Nach dem Login kopieren

按照给定的格式 fmt,把数据封装成字符串 ( 实际上是类似于 C 结构体的字节流 )

struct 中支持的格式如下表:

Format C Type Python type Standard size
x pad byte no value
c char bytes of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer 4
l long integer 4
L unsigned long integer 4
q long long integer 8
Q unsigned long long integer 8
n ssize_t integer
N size_t integer
e -7 float 2
f float float 4
d double float 8
s char[] bytes
p char[] bytes
P void * integer

为了同 C 语言中的结构体交换数据,还要考虑有的 C 或 C++ 编译器使用了字节对齐,通常是以 4 个字节为单位的 32 位系统,故而 struct 根据本地机器字节顺序转换。可以用格式中的第一个字符来改变对齐方式,定义如下:

Character Byte order Size Alignment
@ native native native
= native standard none
<little-endianstandardnone
> big-endian standard none
! network (= big-endian) standard none

发送 WebSocket 报文代码如下:

def write_msg(message):
 data = struct.pack('B', 129) # 写入第一个字节,10000001
 # 写入包长度
 msg_len = len(message)
 if msg_len <= 125:
  data += struct.pack('B', msg_len)
 elif msg_len <= (2 ** 16 - 1):
  data += struct.pack('!BH', 126, msg_len)
 elif msg_len <= (2 ** 64 - 1):
  data += struct.pack('!BQ', 127, msg_len)
 else:
  logging.error('Message is too long!')
  return
 data += bytes(message, encoding='utf-8') # 写入消息内容
 logging.debug(data)
 return data
Nach dem Login kopieren

总结

没有其他能像 WebSocket 一样实现全双工传输的技术了,迄今为止,大部分开发者还是使用 Ajax 轮询来实现,但这是个不太优雅的解决办法,WebSocket 虽然用的人不多,可能是因为协议刚出来的时候有安全性的问题以及兼容的浏览器比较少,但现在都有解决。如果你有这些需求可以考虑使用 WebSocket:

  • 多个用户之间进行交互;

  • 需要频繁地向服务端请求更新数据。

比如弹幕、消息订阅、多玩家游戏、协同编辑、股票基金实时报价、视频会议、在线教育等需要高实时的场景。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

ES6实现全屏滚动插件步骤详解

Vue中watch使用方法总结

Das obige ist der detaillierte Inhalt vonAnalyse der WebSocket-Kommunikationsnutzung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So erreichen Sie Echtzeitkommunikation mit PHP und WebSocket So erreichen Sie Echtzeitkommunikation mit PHP und WebSocket Dec 17, 2023 pm 10:24 PM

Mit der kontinuierlichen Weiterentwicklung der Internettechnologie ist Echtzeitkommunikation zu einem unverzichtbaren Bestandteil des täglichen Lebens geworden. Mit der WebSockets-Technologie kann eine effiziente Echtzeitkommunikation mit geringer Latenz erreicht werden, und PHP als eine der am weitesten verbreiteten Entwicklungssprachen im Internetbereich bietet auch entsprechende WebSocket-Unterstützung. In diesem Artikel wird erläutert, wie Sie mithilfe von PHP und WebSocket eine Echtzeitkommunikation erreichen, und es werden spezifische Codebeispiele bereitgestellt. 1. Was ist WebSocket? WebSocket ist ein Single

PHP und WebSocket: Best Practices für die Echtzeit-Datenübertragung PHP und WebSocket: Best Practices für die Echtzeit-Datenübertragung Dec 18, 2023 pm 02:10 PM

PHP und WebSocket: Best-Practice-Methoden für die Echtzeit-Datenübertragung Einführung: Bei der Entwicklung von Webanwendungen ist die Echtzeit-Datenübertragung eine sehr wichtige technische Anforderung. Das herkömmliche HTTP-Protokoll ist ein Anforderungs-Antwort-Modellprotokoll und kann keine Datenübertragung in Echtzeit effektiv erreichen. Um den Anforderungen der Echtzeit-Datenübertragung gerecht zu werden, wurde das WebSocket-Protokoll entwickelt. WebSocket ist ein Vollduplex-Kommunikationsprotokoll, das eine Möglichkeit zur Vollduplex-Kommunikation über eine einzelne TCP-Verbindung bietet. Im Vergleich zu H

Wie implementiert Java Websocket die Online-Whiteboard-Funktion? Wie implementiert Java Websocket die Online-Whiteboard-Funktion? Dec 17, 2023 pm 10:58 PM

Wie implementiert JavaWebsocket die Online-Whiteboard-Funktion? Im modernen Internetzeitalter legen die Menschen immer mehr Wert auf das Erlebnis der Zusammenarbeit und Interaktion in Echtzeit. Online-Whiteboard ist eine auf Websocket implementierte Funktion, die es mehreren Benutzern ermöglicht, in Echtzeit zusammenzuarbeiten, um dasselbe Zeichenbrett zu bearbeiten und Vorgänge wie Zeichnen und Anmerkungen durchzuführen. Es bietet eine praktische Lösung für Online-Schulungen, Remote-Meetings und Teamzusammenarbeit andere Szenarien. 1. Technischer Hintergrund WebSocket ist ein neues Protokoll, das von HTML5 implementiert wird

SSE und WebSocket SSE und WebSocket Apr 17, 2024 pm 02:18 PM

In diesem Artikel vergleichen wir Server Sent Events (SSE) und WebSockets, beides zuverlässige Methoden zur Übermittlung von Daten. Wir werden sie in acht Aspekten analysieren, darunter Kommunikationsrichtung, zugrunde liegendes Protokoll, Sicherheit, Benutzerfreundlichkeit, Leistung, Nachrichtenstruktur, Benutzerfreundlichkeit und Testtools. Ein Vergleich dieser Aspekte lässt sich wie folgt zusammenfassen: Kategorie Server Sent Event (SSE) WebSocket-Kommunikationsrichtung Einseitig bidirektional Zugrundeliegendes Protokoll HTTP WebSocket-Protokoll Sicherheit Gleich wie HTTP Vorhandene Sicherheitslücken Benutzerfreundlichkeit Einstellungen Einfache Einstellungen Komplexe Leistung Schnelle Nachrichtenversandgeschwindigkeit Betroffen von der Nachrichtenverarbeitung und dem Verbindungsmanagement. Nachrichtenstruktur Nur Text oder Binär. Benutzerfreundlichkeit. Weit verbreitet. Hilfreich für die WebSocket-Integration

PHP-Websocket-Entwicklungshandbuch zur Implementierung der Echtzeit-Übersetzungsfunktion PHP-Websocket-Entwicklungshandbuch zur Implementierung der Echtzeit-Übersetzungsfunktion Dec 18, 2023 pm 05:52 PM

PHP Websocket-Entwicklungshandbuch: Implementierung der Echtzeit-Übersetzungsfunktion Einführung: Mit der Entwicklung des Internets wird Echtzeitkommunikation in verschiedenen Anwendungsszenarien immer wichtiger. Als aufstrebendes Kommunikationsprotokoll bietet Websocket eine gute Unterstützung für Echtzeitkommunikation. Dieser Artikel führt Sie durch ein detailliertes Verständnis der Verwendung von PHP zum Entwickeln von Websocket-Anwendungen und kombiniert die Echtzeitübersetzungsfunktion, um deren spezifische Anwendung zu demonstrieren. 1. Was ist das Websocket-Protokoll? Das Websocket-Protokoll ist ein

golang WebSocket-Programmiertipps: Umgang mit gleichzeitigen Verbindungen golang WebSocket-Programmiertipps: Umgang mit gleichzeitigen Verbindungen Dec 18, 2023 am 10:54 AM

Golang ist eine leistungsstarke Programmiersprache und ihre Verwendung in der WebSocket-Programmierung wird von Entwicklern zunehmend geschätzt. WebSocket ist ein TCP-basiertes Protokoll, das eine bidirektionale Kommunikation zwischen Client und Server ermöglicht. In diesem Artikel stellen wir vor, wie Sie mit Golang einen effizienten WebSocket-Server schreiben, der mehrere gleichzeitige Verbindungen gleichzeitig verarbeitet. Bevor wir die Techniken vorstellen, lernen wir zunächst, was WebSocket ist. Einführung in WebSocketWeb

So verwenden Sie WebSocket für die Dateiübertragung in Golang So verwenden Sie WebSocket für die Dateiübertragung in Golang Dec 18, 2023 am 09:06 AM

So verwenden Sie WebSocket für die Dateiübertragung in Golang. WebSocket ist ein Netzwerkprotokoll, das die bidirektionale Kommunikation unterstützt und eine dauerhafte Verbindung zwischen dem Browser und dem Server herstellen kann. In Golang können wir die Drittanbieterbibliothek Gorilla/Websocket verwenden, um die WebSocket-Funktionalität zu implementieren. In diesem Artikel wird erläutert, wie Sie Golang- und Gorilla/Websocket-Bibliotheken für die Dateiübertragung verwenden. Zuerst müssen wir Gorilla installieren

So verwenden Sie Java und WebSocket, um den Push von Aktienkursen in Echtzeit zu implementieren So verwenden Sie Java und WebSocket, um den Push von Aktienkursen in Echtzeit zu implementieren Dec 17, 2023 pm 09:15 PM

So implementieren Sie mithilfe von Java und WebSocket einen Aktienkurs-Push in Echtzeit. Einführung: Mit der rasanten Entwicklung des Internets ist der Echtzeit-Aktienkurs-Push zu einem der Schwerpunkte der Anleger geworden. Die traditionelle Börsen-Push-Methode weist Probleme wie hohe Verzögerungen und langsame Aktualisierungsgeschwindigkeit auf. Für Anleger kann die Unfähigkeit, rechtzeitig die neuesten Börseninformationen zu erhalten, zu Fehlern bei Anlageentscheidungen führen. Echtzeit-Aktienkurs-Push auf Basis von Java und WebSocket kann dieses Problem effektiv lösen, sodass Anleger so schnell wie möglich die neuesten Aktienkursinformationen erhalten.

See all articles