Maison interface Web js tutoriel Analyse de l'utilisation des communications WebSocket

Analyse de l'utilisation des communications WebSocket

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

Cette fois, je vais vous apporter une analyse de l'utilisation de la communication WebSocket. Quelles sont les précautions lors de l'analyse de l'utilisation de la communication WebSocket. Ce qui suit est un cas pratique, jetons un coup d'œil.

Qu'est-ce que WebSocket ?

WebSocket est un protocole standard pour le transfert de données bidirectionnel entre client et serveur. Mais cela n'a rien à voir avec HTTP. Il s'agit d'une implémentation indépendante basée sur TCP.

Dans le passé, si le client voulait connaître la progression du traitement du serveur, il devait constamment utiliser Ajax pour interroger, afin que le navigateur envoie une requête au serveur toutes les quelques secondes, ce qui mettait un beaucoup de pression sur le serveur. Un autre type d'interrogation consiste à utiliser une interrogation longue, qui est similaire à un appel téléphonique. Elle ne raccrochera pas tant qu'un message ne sera pas reçu. En d'autres termes, une fois que le client aura établi une connexion, s'il n'y a pas de message, la réponse sera envoyée. ne soit pas restitué au client, la phase de connexion est toujours bloquée.

Et WebSocket résout ces problèmes de HTTP. Une fois que le serveur a terminé la mise à niveau du protocole (HTTP -> WebSocket), le serveur peut activement transmettre des informations au client, résolvant ainsi le problème de délai de synchronisation causé par l'interrogation. Étant donné que WebSocket ne nécessite qu'une seule négociation HTTP, le serveur peut continuer à communiquer avec le client jusqu'à ce que la connexion soit fermée. Cela élimine le besoin pour le serveur d'analyser à plusieurs reprises le protocole HTTP et réduit la surcharge des ressources.

Avec l'avancement des nouvelles normes, WebSocket est devenu plus mature et divers navigateurs grand public prennent mieux en charge WebSocket (non compatible avec les versions inférieures d'IE, IE inférieures à 10) , vous pouvez y jeter un œil quand vous avez le temps.

Lors de l'utilisation de WebSocket, l'utilisation frontale est relativement standardisée. js prend en charge le protocole ws. Cela ressemble à un protocole Socket légèrement encapsulé, mais vous devez conserver le protocole. Socket vous-même auparavant, les connexions peuvent désormais être établies de manière plus standard.

Parlons du processus de communication de WebSocket en détail en fonction de l'image ci-dessus.

Établir la connexion

En-tête du message de demande du client

Message de demande du client :

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13
Copier après la connexion

Différences à partir de messages HTTP traditionnels :

Upgrade: websocket
Connection: Upgrade
Copier après la connexion

Ces deux lignes indiquent que le protocole WebSocket est initié.

Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13
Copier après la connexion

Sec-WebSocket-Key est généré aléatoirement par le navigateur et offre une protection de base contre les connexions malveillantes ou involontaires.

Sec-WebSocket-Version indique la version de WebSocket. Au départ, il y avait trop de protocoles WebSocket, et différents fabricants avaient leurs propres versions de protocole, mais maintenant c'est réglé. Si le serveur ne prend pas en charge cette version, un Sec-WebSocket-Versionheader doit être renvoyé, qui contient le numéro de version pris en charge par le serveur.

Créer un objet WebSocket :

var ws = new websocket("ws://127.0.0.1:8001");
Copier après la connexion

ws signifie utiliser le protocole WebSocket, suivi de l'adresse et du port

Code client complet :

<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>
Copier après la connexion

En-tête du message de réponse du serveur

Tout d'abord, jetons un œil au message de réponse du serveur :

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
Copier après la connexion

Expliquons-le ligne par ligne

  • Tout d'abord, 101 code d'état indique que le serveur a compris la demande du client et informera le client d'utiliser un protocole différent pour compléter la demande via l'en-tête du message de mise à niveau

  • Ensuite, Sec-WebSocket-Accept est la Sec-WebSocket-Key qui a été confirmée par le serveur et chiffrée

  • ;

    Enfin, Sec-WebSocket-Protocol représente le protocole final utilisé.

Méthode de calcul de Sec-WebSocket-Accept :

  • Splice Sec-WebSocket-Key avec 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 ;

  • Calculez le résumé via SHA1 et convertissez-le en une chaîne base64.

注意: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()
Copier après la connexion

进行通信

服务端解析 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
Copier après la connexion

服务端发送 WebSocket 报文

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

struct 模块解析

struct.pack(fmt, v1, v2, ...)
Copier après la connexion

按照给定的格式 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
Copier après la connexion

总结

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

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

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

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

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

推荐阅读:

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

Vue中watch使用方法总结

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment réaliser une communication en temps réel en utilisant PHP et WebSocket Comment réaliser une communication en temps réel en utilisant PHP et WebSocket Dec 17, 2023 pm 10:24 PM

Avec le développement continu de la technologie Internet, la communication en temps réel est devenue un élément indispensable de la vie quotidienne. Une communication en temps réel efficace et à faible latence peut être obtenue grâce à la technologie WebSockets, et PHP, en tant que l'un des langages de développement les plus utilisés dans le domaine Internet, fournit également la prise en charge WebSocket correspondante. Cet article explique comment utiliser PHP et WebSocket pour établir une communication en temps réel et fournit des exemples de code spécifiques. 1. Qu'est-ce que WebSocket ?

PHP et WebSocket : bonnes pratiques pour le transfert de données en temps réel PHP et WebSocket : bonnes pratiques pour le transfert de données en temps réel Dec 18, 2023 pm 02:10 PM

PHP et WebSocket : meilleures pratiques pour le transfert de données en temps réel Introduction : Dans le développement d'applications Web, le transfert de données en temps réel est une exigence technique très importante. Le protocole HTTP traditionnel est un protocole de modèle requête-réponse et ne peut pas assurer efficacement la transmission de données en temps réel. Afin de répondre aux besoins de transmission de données en temps réel, le protocole WebSocket a vu le jour. WebSocket est un protocole de communication full-duplex qui permet de communiquer en full-duplex via une seule connexion TCP. Comparé à H

Comment Java Websocket implémente-t-il la fonction de tableau blanc en ligne ? Comment Java Websocket implémente-t-il la fonction de tableau blanc en ligne ? Dec 17, 2023 pm 10:58 PM

Comment JavaWebsocket implémente-t-il la fonction de tableau blanc en ligne ? À l’ère d’Internet moderne, les gens accordent de plus en plus d’attention à l’expérience de collaboration et d’interaction en temps réel. Le tableau blanc en ligne est une fonction implémentée sur la base de Websocket. Il permet à plusieurs utilisateurs de collaborer en temps réel pour modifier la même planche à dessin et effectuer des opérations telles que le dessin et l'annotation. Il constitue une solution pratique pour l'enseignement en ligne, les réunions à distance, la collaboration en équipe et. d'autres scénarios. 1. Contexte technique WebSocket est un nouveau protocole fourni par HTML5 qu'il implémente.

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

Dans cet article, nous comparerons les événements envoyés par le serveur (SSE) et les WebSockets, qui sont tous deux des méthodes fiables pour fournir des données. Nous les analyserons sous huit aspects, notamment la direction de la communication, le protocole sous-jacent, la sécurité, la facilité d'utilisation, les performances, la structure des messages, la facilité d'utilisation et les outils de test. Une comparaison de ces aspects est résumée comme suit : Catégorie Événement envoyé par le serveur (SSE) Direction de communication WebSocket Unidirectionnel Bidirectionnel Protocole sous-jacent HTTP Sécurité du protocole WebSocket Identique à HTTP Failles de sécurité existantes Facilité d'utilisation Paramètres Paramètres simples Performances complexes Vitesse d'envoi rapide des messages Affecté par le traitement des messages et la gestion des connexions Structure du message Texte brut ou binaire Facilité d'utilisation Largement disponible Utile pour l'intégration de WebSocket

Guide de développement PHP Websocket pour implémenter la fonction de traduction en temps réel Guide de développement PHP Websocket pour implémenter la fonction de traduction en temps réel Dec 18, 2023 pm 05:52 PM

Guide de développement PHP Websocket : Implémentation de la fonction de traduction en temps réel Introduction : Avec le développement d'Internet, la communication en temps réel devient de plus en plus importante dans divers scénarios d'application. En tant que protocole de communication émergent, Websocket offre une bonne prise en charge de la communication en temps réel. Cet article vous expliquera en détail comment utiliser PHP pour développer des applications Websocket et combinera la fonction de traduction en temps réel pour démontrer son application spécifique. 1. Qu'est-ce que le protocole Websocket ? Le protocole Websocket est un

Conseils de programmation Golang WebSocket : gestion des connexions simultanées Conseils de programmation Golang WebSocket : gestion des connexions simultanées Dec 18, 2023 am 10:54 AM

Golang est un langage de programmation puissant et son utilisation dans la programmation WebSocket est de plus en plus appréciée par les développeurs. WebSocket est un protocole basé sur TCP qui permet une communication bidirectionnelle entre le client et le serveur. Dans cet article, nous expliquerons comment utiliser Golang pour écrire un serveur WebSocket efficace qui gère plusieurs connexions simultanées en même temps. Avant de présenter les techniques, apprenons d'abord ce qu'est WebSocket. Introduction à WebSocketWeb

Comment utiliser WebSocket pour le transfert de fichiers dans Golang Comment utiliser WebSocket pour le transfert de fichiers dans Golang Dec 18, 2023 am 09:06 AM

Comment utiliser WebSocket pour le transfert de fichiers dans Golang WebSocket est un protocole réseau qui prend en charge la communication bidirectionnelle et peut établir une connexion persistante entre le navigateur et le serveur. Dans Golang, nous pouvons utiliser la bibliothèque tierce gorilla/websocket pour implémenter la fonctionnalité WebSocket. Cet article explique comment utiliser les bibliothèques Golang et Gorilla/Websocket pour le transfert de fichiers. Tout d'abord, nous devons installer Gorilla

Comment utiliser Java et WebSocket pour mettre en œuvre une poussée des cotations boursières en temps réel Comment utiliser Java et WebSocket pour mettre en œuvre une poussée des cotations boursières en temps réel Dec 17, 2023 pm 09:15 PM

Comment utiliser Java et WebSocket pour mettre en œuvre une cotation boursière en temps réel Introduction : Avec le développement rapide d'Internet, la cotation boursière en temps réel est devenue l'une des priorités des investisseurs. La méthode traditionnelle de poussée boursière présente des problèmes tels qu'un retard élevé et une vitesse de rafraîchissement lente. Pour les investisseurs, l'incapacité d'obtenir les dernières informations boursières en temps opportun peut entraîner des erreurs dans les décisions d'investissement. La cotation boursière en temps réel basée sur Java et WebSocket peut résoudre efficacement ce problème, permettant aux investisseurs d'obtenir les dernières informations sur le cours des actions dès que possible.

See all articles