IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> WebSocket -> 正文阅读

[网络协议]WebSocket

介绍

RFC 6455 规范中描述的 WebSocket 协议提供了一种通过长连接在浏览器和服务器之间交换数据的方法。 数据可以作为“数据包”双向传递,而不会中断连接并且不需要额外的 HTTP 请求。

WebSocket 特别适用于需要持续数据交换的服务,例如 网络游戏、实时交易系统等。

简单实例

要打开 websocket 连接,我们需要使用 url 中的特殊协议 ws 创建新的 WebSocket:

let socket = new WebSocket("ws://127.0.0.1:8001");

还有加密的 wss:// 协议。 这就像 websocket 的 HTTPS。
一旦创建了socket,我们就应该监听它上面的事件。 总共有4个事件:

  • open – 连接建立
  • message – 消息发送
  • error – 错误处理
  • close – 连接关闭
    如果我们想发送消息,可以使用: socket.send(data) ,下面是一个简单实例基于js:
let socket = new WebSocket("wss://127.0.0.1:8001/websocket/demo/hello");

socket.onopen = function(e) {
  alert("[open] Connection established");
  alert("Sending to server");
  socket.send("My name is John");
};

socket.onmessage = function(event) {
  alert(`[message] Data received from server: ${event.data}`);
};

socket.onclose = function(event) {
  if (event.wasClean) {
    alert(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
  } else {
    // e.g. server process killed or network down
    // event.code is usually 1006 in this case
    alert('[close] Connection died');
  }
};

socket.onerror = function(error) {
  alert(`[error]`);
};

websocket创建

new WebSocket(url)后,它会立即开始连接。
在连接期间,浏览器(headers)询问服务器:“是否支持Websocket ?” 如果服务器响应“是”,那么会话将继续在WebSocket 协议中进行,非HTTP。
在这里插入图片描述
下面一个简单的请求header信息

GET /chat
Host: javascript.info
Origin: https://127.0.0.1:8001
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
Sec-WebSocket-Version: 13
  • Origin – 客户端页面的来源,例如https://127.0.0.1:8001。 WebSocket 对象本质上是跨域的。 没有特殊的标题或其他限制。 旧服务器无论如何都无法处理 WebSocket,因此不存在兼容性问题。 但是 Origin 标头很重要,因为它允许服务器决定是否与该网站通信WebSocket
  • Connection: Upgrade——表示客户端想要更改协议。
  • Upgrade:websocket——请求的协议是“websocket”。
  • Sec-WebSocket-Key – 浏览器生成的随机密钥,用于确保服务器支持 WebSocket 协议。 防止代理缓存任何后续通信是随机的。
  • Sec-WebSocket-Version - WebSocket 协议版本

如果服务端支持WebSocket,它会发生相应码101:

101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: hsBlbuDTkk24srzEOTBUlZAlC2g=

这里的 Sec-WebSocket-Accept 是 Sec-WebSocket-Key,使用特殊算法重新编码。 浏览器能够解析该编码, 来确认服务端支持该WebSocket协议。
之后,使用 WebSocket 协议传输数据,我们很快就会看到它的结构(“frames”)。 而不是传统意义的 HTTP

扩展和子协议

请求header中可以增加: Sec-WebSocket-Extensions 和 Sec-WebSocket-Protocol

let socket = new WebSocket("wss://127.0.0.1:8001/chat", ["soap", "wamp"]);

请求如下

GET /chat
Host: javascript.info
Upgrade: websocket
Connection: Upgrade
Origin: https://127.0.0.1:8001
Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: deflate-frame
Sec-WebSocket-Protocol: soap, wamp

相应

101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: hsBlbuDTkk24srzEOTBUlZAlC2g=
Sec-WebSocket-Extensions: deflate-frame
Sec-WebSocket-Protocol: soap
  • Sec-WebSocket-Extensions:deflate-frame 表示浏览器支持数据压缩。 扩展是与传输数据相关的东西,是扩展 WebSocket 协议的功能。 Sec-WebSocket-Extensions 由浏览器自动发送,其中包含它支持的所有扩展的列表。
  • Sec-WebSocket-Protocol:soap, wamp 意味着我们不仅要传输任何数据,还要传输 SOAP 或 WAMP(“The WebSocket Application Messaging Protocol”)协议中的数据。 WebSocket 子协议在 IANA 目录中注册。 因此,此headers描述了我们将要使用的数据格式。

数据传输

WebSocket 通信由“frames”——数据片段组成,可以从任何一方发送,并且可以有以下几种:

  • text frames ——包含各方相互发送的文本数据。
  • binary data frames ——包含各方相互发送的二进制数据。
  • ping/pong frames —— 用于检查连接,从服务器发送,浏览器自动响应这些。
  • connection close frame —— 和其他一些服务框架。

在浏览器中,我们只直接使用文本或二进制帧
WebSocket .send() 方法可以发送文本或二进制数据
调用 socket.send(body) 允许使用字符串或二进制格式的正文,包括 Blob、ArrayBuffer 等。无需设置:以任何格式发送即可。

当我们收到数据时,文本总是以字符串的形式出现。对于二进制数据,我们可以在 Blob 和 ArrayBuffer 格式之间进行选择。

这是由 socket.binaryType 属性设置的,默认为“blob”,因此二进制数据以 Blob 对象的形式出现。

socket.binaryType = "arraybuffer";
socket.onmessage = (event) => {
  // event.data is either a string (if text) or arraybuffer (if binary)
};

发送限制

想象一下,我们的应用程序正在生成大量要发送的数据。 但是用户的网络连接速度很慢。

我们可以一次又一次地调用 socket.send(data)。 但是数据将被缓冲(stored)在内存中,并仅在网络速度允许的情况下以最快的速度发送出去。

socket.bufferedAmount 属性存储了此时有多少字节保持缓冲,等待通过网络发送。

setInterval(() => {
  if (socket.bufferedAmount == 0) {
    socket.send(moreData());
  }
}, 100);

连接关闭

通常,当一方想要关闭连接时(浏览器和服务器具有相同的权限),他们会发送一个带有数字代码和文本原因的“connection close frame”。

socket.close([code], [reason]);
  • code 一个特殊的 WebSocket code(可选)
  • reason 关闭原因(可选)
socket.close(1000, "Work complete");

socket.onclose = event => {
  // event.code === 1000
  // event.reason === "Work complete"
  // event.wasClean === true (clean close)
};

最常见的代码值:

  • 1000 - 默认的正常关闭(如果没有提供代码则使用)
  • 1006 - 无法手动设置此类代码,表示连接丢失(无关闭帧)
  • 1001 - 服务器正在关闭,或浏览器离开页面
  • 1009 – 消息太大而无法处理
  • 1011 - 服务器上出现意外错误

连接状态

要获取连接状态,另外还有带有值的 socket.readyState 属性:

  • 0 – “CONNECTING”:连接尚未建立,
  • 1 – “OPEN”:打开并连接,
  • 2 – “CLOSING”:连接正在关闭,
  • 3 – “CLOSED”:连接已关闭。
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:34:57  更:2022-10-31 12:36:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 7:31:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码