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

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

2024-08-04 00:08:22 前端知识 前端哥 324 14 我要收藏

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;
    // 检测心跳的间隔ID
    let 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
      // CLOSED
      if (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 messages
      webSocket.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对象来读写缓冲区 按照有符号的8位数字读取
            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 errors
      webSocket.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

转载请注明出处或者链接地址:https://www.qianduange.cn//article/14744.html
标签
websocket
评论
发布的文章

JQuery中的load()、$

2024-05-10 08:05:15

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!