HTML5 WebSocket介绍与基本使用(解析服务端返回的二进制数据)

WebSocket基本介绍

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

WebSocket 状态

在上面代码中我们通过WebSocket()构造函数来构造一个ws实例。对应的这个实例中有只读属性 readyState 表示连接状态四个状态,对应的分别有四个不同的值,具体如下:

状态说明
WebSocket.CONNECTING0表示连接尚未建立
WebSocket.OPEN1表示连接已建立,可以进行通信
WebSocket.CLOSING2表示连接正在进行关闭
WebSocket.CLOSED3表示连接已经关闭或者连接不能打开

WebSocket 事件

整个ws建立的过程有四个比较重要的事件,分别是:

  1. open阶段:WebSocket.onopen属性定义一个事件处理程序,当WebSocket 的连接状态readyState 变为1时调用;这意味着当前连接已经准备好发送和接受数据。这个事件处理程序通过 事件(建立连接时)触发
  2. message:message 事件会在 WebSocket 接收到新消息时被触发
  3. close:WebSocket.onclose 属性返回一个事件监听器,这个事件监听器将在 WebSocket 连接的readyState 变为 CLOSED时被调用,它接收一个名字为“close”的 CloseEvent 事件
  4. error:当websocket的连接由于一些错误事件的发生 (例如无法发送一些数据) 而被关闭时,一个error事件将被引发

WebSocket 方法

ws中我们常用的有如下两个方法:

  1. send:使用连接发送数据
  2. close:关闭连接

HTML中建立ws

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>websocket-demo</title>
</head><body></body>
<script>// 建立ws连接const wbSocket = () => {// ws实例let webSocket = null;// 检测心跳的间隔IDlet intervalID = null;const connect = async () => {// 服务端ws的地址const wsUrl = 'ws://10.199.161.17:9010/ws?deviceId=A51a007F-0620-467B-8A4a-c8a6c9aD69FD&protocolVersion=3'// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState// CLOSEDif (webSocket && webSocket.readyState !== 3) {return;}// Create WebSocket connection.webSocket = new WebSocket(wsUrl);// 连接已经准备好发送和接受数据webSocket.addEventListener("open", (event) => {webSocket.send("Hello Server, connection has build", event);});// Listen for messageswebSocket.addEventListener("message", async (event) => {console.log("Message from server: ", event.data);const receivedData = event.data;if (receivedData instanceof Blob) {try {const buffer = await event.data.arrayBuffer()// 建立DateView对象来读写缓冲区const view = new Int8Array(buffer);// 将类数组view转化为数组,方便读取const list = Array.from(view)console.log(list);} catch (error) {console.log('解析blob出错', error.message);}} else {console.log('接受到的数据');}});// Listen for possible errorswebSocket.addEventListener("error", (event) => {console.log("WebSocket error: ", event);});webSocket.addEventListener("close", event => {console.log("socket closed ", event.data);// 将webSocket 设为Null, 不再发送心跳 等待重新建立连接clearInterval(intervalID)webSocket = null;intervalID = null;});}setInterval(() => {// 如果有socket实例并且有心跳就直接返回if (webSocket && webSocket) return// 无ws实力 or 心跳id则建立ws连接connect()}, 5 * 1000)}wbSocket()</script></html>

可以看到在上面代码中我们对服务端返回给前端的值做了一层判定,有时服务端在特定的场景下会使用java中的netty这个工具包返回给前端的数据是二进制的,就需要前端判断之后自己再使用arrayBuffer这个API自己转一下。
如果服务端此时返回的是一个正常的数据而非Blob的话,那就可以直接在event.data中获取就可以了。
需要注意一点是ArrayBuffer是一个表示原始二进制数据的缓冲区,是一个字节数组,并不能直接操作ArrayBuffer中的内容。需要通过DataView对象来操作

浏览器中查看ws

在这里插入图片描述
如果打印出上面代码中的buffer的话console.log(111, buffer);会在浏览器如下显示:
在这里插入图片描述
我们点击右侧的那个点之后,会跳转到浏览器的内存检查器,查看对应的值以及存这些值的地址。
在这里插入图片描述

参考资料

WebSocket
HTML5 WebSocket
ArrayBuffer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/17938.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(vue)vue项目实现语音播报

(vue)vue项目实现语音播报 解决参考1&#xff1a; 在 Vue 项目中&#xff0c;你可以使用 Web Speech API 中的 SpeechSynthesis 接口来实现文本内容的自动朗读。下面是一个示例&#xff1a; 1.在 Vue 组件的模板中添加一个按钮&#xff0c;用于触发朗读&#xff1a; <templa…

【数据结构】map和set

文章目录 map和set1. 关联式容器2. 键值对3. 树形结构的关联式容器3.1 set3.2 set的模板参数列表3.3 set的构造3.4 set的使用举例 4. map4.1 map的使用 5. multiset5.1 multiset的使用 6. multimap7. 经典题目 map和set 1. 关联式容器 vector、list、deque这些容器都是序列式…

TIOBE 7月编程语言榜出炉,这个语言强势突围,前三发生重大变化

TIOBE 公布了 2023 年 7 月的编程指数信息&#xff0c;在这个月&#xff0c;语言榜有什么新变化&#xff0c;让我们一起去看看吧&#xff01; JavaScript 创历史新高 几个月前&#xff0c;编程语言 C 占据了 TIOBE 指数的第 3 位&#xff08;超过了 Java&#xff09;。 但C的…

df -h 查看Used+Avail != Size

问题描述&#xff1a; 在测试过程中发现&#xff0c;该机器的根目录空间 41G 5.7G ! 50G&#xff0c;即 Used Avail ! Size 问题原因&#xff1a; 经过搜索&#xff0c;了解到这种情况可能是Linux系统默认的文件保留块导致的&#xff08;Linux系统默认保留5%的容量作为应急…

数据库-表的增删改查

这里写目录标题 新增&#xff08;Create&#xff09;查询条件查询运算符逻辑运算符分页查询 修改&#xff08;Update&#xff09;删除&#xff08;Delete&#xff09; 注释&#xff1a;在SQL中可以使用“–空格描述”来表示注释说明 新增&#xff08;Create&#xff09; 语法…

音频编码流程 ----- PCM编码为AAC格式

文章目录 1.音频编码流程2.编码函数API含义解释3.音频编码实战Demo PCM转AAC格式 1.音频编码流程 2.编码函数API含义解释 av_frame_make_writable 确保帧数据可写&#xff0c;尽可能避免数据复制.如果帧可写&#xff0c;则不执行任何操作&#xff0c;如果不可写&#xff0c;则…

UE5_ 地编_siki海岛

1.开启水插件 制作流体 2.开启大陆地形的插件

wsl 1和wsl 2在形式上的区别

完整的比较请参考&#xff1a; 比较 WSL 版本 | Microsoft Learn 如果是已经安装完成&#xff0c;但安装的是wsl &#xff0c;之后想由 wsl 1升级到wsl 2&#xff0c;请参考&#xff1a;WSL1升级至WSL2_wsl1升级wsl2_goldVitaminC的博客-CSDN博客 在形式上&#xff0c;wsl 1是…

Java 设计模式 随笔1 监听器/观察者

0. 不由自主&#xff0c;恍恍惚惚&#xff0c;又走回头路&#xff0c;再看一眼有过的幸福… 太棒了流沙!!! 0.1 引用 https://blog.csdn.net/majunzhu/article/details/100869562 ApplicationEvent事件机制源码分析 单机环境下优雅地使用事件驱动进行代码解耦 1. JDK 1.1 …

测试员如何突破自我的瓶颈?我有几点看法

前阵子我自己也对如何“突破瓶颈”思考过&#xff0c;我觉得“突破瓶颈”、“弥补短板”等等都大同小异&#xff0c;从古至今就是测试员们津津乐道的话题。我也对自己该如何“突破瓶颈”总结了几点&#xff0c;跟大家分享下&#xff1a; 1、“常立志、立长志”。“立志”就是目…

测试管理能力—如何带领一个快乐和成功的测试团队

目录 前言&#xff1a; 技巧# 1)业务知识和技术技能 技巧# 2)努力评估和有效的分配工作 技巧# 3)尽量不要超量提交 技巧# 4)沟通和人际交往能力 学习如何说“不”: 谈判技巧: 鼓励合作与发展: 您将看到两个好处: 向高层管理人员汇报和电子邮件交流: 团队会议: 给空间: 做第…

日撸java三百行day75-76

文章目录 说明通用BP神经网络1.通用神经网络2.代码理解2.1 FullAnn类2.2 forward函数2.3 backPropagation函数2.4 不同激活函数的对比结果 说明 闵老师的文章链接&#xff1a; 日撸 Java 三百行&#xff08;总述&#xff09;_minfanphd的博客-CSDN博客 自己也把手敲的代码放在…