概述

通过前三篇博客,我们能够了解在通过WebSocket发送数据之前,我们需要传递的数据是如何变成ArrayBuffer二进制数据的;在我们收到二进制数据之后,我们又如何将其变成了JavaScript中的常见数据类型。

本文作为WebSocket系列的第四篇内容,将会用一个简单的IM聊天应用把整个WebSocket传输二进制数据类型的内容连接起来,让用户对整个WebSocket传输二进制数据的方法有个了解。

本文的主要内容如下:

  • 如何设计一个二进制协议

  • WebSocket如何发送二进制数据

  • WebSocket如何处理接收的二进制数据

之前的博客我们介绍过了WebSocket基础知识,数字类型和字符串类型与二进制数据间的转换,如果没有相关的基础,建议先依次阅读以下文章:

  • WebSocket系列之基础知识入门篇

  • WebSocket系列之JavaScript中数字数据如何转换为二进制数据

  • WebSocket系列之字符串如何与二进制数据进行转换

如何设计一个二进制协议

什么是协议

协议,网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定,计算机之间才能相互通信交流。它的三要素是:语法、语义、时序。

通过百度百科中的介绍,我们对协议的概念有了一个基础的了解。通俗来说,协议就是通信双方约定好的一套规则。

为什么要设计协议

没有规矩不成方圆。通信双方只有通过协议,才能够识别对方发送的数据内容。

我们应该如何设计这套协议

首先,协议的设计应该能够区分不同的各个数据包;其次,它还需要具备一定的兼容性。

根据上述两点要求,我们设计了一套简单的IM聊天协议,支持文本、图片、文件三种消息。这套协议是按照最简单的思路来设计的,因此也只是给大家一个参考的观点,在真正的线上使用场景中,协议会比本文中的复杂和更加有层次。具体格式如下:

{"id": "short", // 消息类型,1是文本协议格式;2是图片协议格式;3是文件协议格式"sender": "long", // 发送用户唯一id"reciever": "long", // 接受用户唯一id"data": "string" // 消息内容,如果是文本协议则为文本内容;如果是图片协议则为图片地址;如果是文件协议则为文件地址
}

这套协议如何使用

发送消息

从协议格式可知,将上述数据按照上述固定顺序放入ArrayBuffer中,即可得到一个有特定含义的二进制数据。例如:

{"id": 1,"sender": "123","reciever": "456","data": "Hellow World"
}

当我们需要发送此消息时,只需要:

  1. 在前2个Byte放入id

  2. 接下来8个Byte中放入sender

  3. 再接下来8个Byte放入reciever

  4. 最后紧接着放入一个string类型(以WebSocket系列之字符串如何与二进制数据进行转换博客中的格式为例,先将字符串长度构造成一个int类型,放在前4个Byte中,接下来将string类型编码后放入)。

此数据就完全按照协议构造完成了。我们只需将次协议通过WebSocket发送即可。具体方法将会在后面章节中说明。

接收消息

从协议格式可知,当我们收到一条消息时,只需要按照协议规范来进行反向解析即可。例如:

{"id": 1,"sender": "123","reciever": "456","data": "Hellow World"
}

如果发送端发送的数据仍然为此消息,我们的解析顺序为:

  1. 先根据前2个Byte读取一个Short类型的id数值。

  2. 将接下来的8个Byte读取为Long类型的sender字段。

  3. 再接下来的8个Byte读取为Long类型的reciever字段。

  4. 接下来读取一个string类型(以发送消息这一节的数据为例,先读取4个Byte长度的int类型字符串长度,然后再根据长度读取字符串即可)。

扩展此协议

当此协议字段无法满足并且已经在线上使用时,我们应该如何扩展呢?

根据我们的写入和读取步骤,我们可以知道:**每次我们读取的二进制数据可以认为是一个格式固定的数据(string类型在构造时会有长度信息,因此认为也是长度相对固定),所以我们在读取二进制数据时读取的长度也是固定的。**因此,我们在扩展时只需要往协议后面增加字段即可。

  • 扩展前的应用仍然会读取之前已经确定的数据协议,只需要保证内容不变,那么功能也不会变。

  • 扩展后的应用能够解析扩展后的协议,因此得到更多的数据,从而可以实现更多的功能。

WebSocket如何发送二进制数据

通过如何设计一个二进制协议一章,我们知道了如何定义WebSocket传输的二进制数据格式。下面,我们来看下如何在WebSocket中发送二进制数据:

let arrayBuffer = getArrayBufferMessagesFromUser(); // 获取用户需要发送的消息数据,为一个ArrayBuffer对象
let webSocket = getWebSocket(); // 获取已经连接成功的WebSocket实例websocket.binaryType = 'arraybuffer'; // 指定WebSocket接受ArrayBuffer实例作为参数webSocket.send(arrayBuffer);

通过上面的示例我们可以知道,WebSocket在发送string类型的数据或者ArrayBuffer类型的数据时,使用的API接口都是send方法,我们只需要在WebSocket初始化后指定传输类型binaryType即可。

WebSocket如何处理接收的二进制数据

通过WebSocket如何发送二进制数据一章,我们知道了如何发送二进制数据。接下来,让我们开看下如何处理WebSocket接收到的二进制数据:

let webSocket = getWebSocket(); // 获取已经连接成功的WebSocket实例websocket.binaryType = 'arraybuffer'; // 指定WebSocket接受ArrayBuffer实例作为参数webSocket.addEventListener('message', (message) => {let arrayBuffer = message.data; // 获取用户接收到的消息数据,为一个ArrayBuffer对象let data = parseMessage(arrayBuffer); // 解析二进制数据
});

通过上面的示例我们可以知道,当我们在建立连接时指定了传输类型binaryType为ArrayBuffer之后,我们通过WebSocket收到的数据也是一个ArrayBuffer实例。我们只需要根据第一章讲解的方式进行解析即可。

总结

本文作为WebSocket系列的第四篇,通过一个IM聊天应用的示例将前三篇博客分享的内容串联起来,给读者完整介绍了在WebSocket中使用二进制数据进行传输的方法以及相关的数据类型转换。

通过前面4篇博客的内容,读者可以根据自己的需求快速的构造和封装WebSocket进行二进制数据传输,基本能够串联整个应用流程。

WebSocket系列下一篇文章将会介绍在线上环境中,如何保证WebSocket的连接,以及线上可能遇到的问题。通过应对WebSocket可能出现的问题,我们能够让整个长连接更加健壮。

WebSocket系列之二进制数据设计与传输相关推荐

  1. h5如何上传文件二进制流_前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输...

    HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...

  2. websocket系列:基于tio-websocket-spring-boot-starter实现二进制数据发送

    前言 昨天收到读者私信,咨询怎么基于Tio实现二进制数据的发送.看到自己写的专栏有人订阅并主动咨询交流还是非常开心的. 今天立刻安排基于tio-websocket-spring-boot-starte ...

  3. websocket服务端和html客户端进行二进制数据交互

    一.概念和理论理解 1.HTTP HTTP 是基于请求响应式的,即通信只能由客户端发起,服务端做出响应,无状态,无连接. 无状态:每次连接只处理一个请求,请求结束后断开连接. 无连接:对于事务处理没有 ...

  4. java字符串 直接能网络传输吗_atitit.二进制数据无损转字符串网络传输

    atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 gbk会造成信息丢失 由于有些字符在gbk字符集中找不到对应的字符,所以默认使用编码63 ...

  5. java xml二进制流传输_XML中二进制数据的处理方法

    XML中二进制数据的处理方法 在xml中,所有的数据都是以文本的形式来显示,但是二进制数据不能直接以文本格式来表示,那xml又是怎么处理二进制数据的呢?下面就来探讨一下. 为了简单和通用性,xml被设 ...

  6. c++传输二进制数据

    文章目录 一.前提 二.二进制和指针相关概念 1.二进制数据传输的本质 2.指针相关概念 (1)float* 和char*类型的指针有什么区别吗 (2)c语言关于指针和长度的理解 3.二进制传输步骤 ...

  7. 房卡麻将分析系列 牌局回放 之 数据设计

    敬请关注微信共众号:红孩儿的游戏开发之路 房卡麻将分析系列 "牌局回放" 之 数据设计 最近几个月,"房卡"棋牌游戏成为了资本追逐的热点,基于微信的广大用户和社 ...

  8. 汇川小型PLC梯形图编程系列教程(七):数值存储与二进制数据知识详解

    原文链接:汇川小型PLC梯形图编程系列教程(七):数值存储与二进制数据知识详解 PLC数据存储原理简介 H123U小型PLC内部采用的是32位的处理器,PLC中的数据处理和电脑中的数据处理基本是一致的 ...

  9. python uint8 与字符串,websocket涉及ArrayBuffer、Uint8Array与python3字符串、二进制数据相互转换...

    很多websocket传输数据是ArrayBuffer形式,但是python中没有这数据类型,关于2者怎么转化我看网上讲的少记录下,方便大家少踩坑. 如下图t.data是websocket接收的Arr ...

最新文章

  1. 腾讯天衍实验室夺世界机器人大赛双冠军,新算法突破脑机接口瓶颈
  2. 【干货】机器学习经典书PRML 最新 Python 3 代码实现,附最全 PRML 笔记视频学习资料...
  3. 使用fswatch工具进行golang的热编译
  4. Mac环境下配置Java开发环境(jdk+maven+tomcat+idea)
  5. xml python2.6_如何使用前缀选项解析python 2.6中的参数为-f file.xml
  6. 布隆过滤器避免redis缓存穿透
  7. python mysql查表_python进阶(十、mysql:单表查询)
  8. unity3d生命周期
  9. 学习索引结构的一些案例——Jeff Dean在SystemML会议上发布的论文(中)
  10. 小雪节气艺术字体设计PNG素材 | 希望可以温暖到你了
  11. SQLPrompt 安装后sql上看不到菜单
  12. 建造者模式(Java与Kotlin版)
  13. 跨平台APP----对Cordova,APPCan,DCloud,APICloud四大平台的分析
  14. 思科交换机(cisco)开启802.1x认证
  15. C语言练习:第二大整数
  16. hmcl手机版下载_hmcl启动器
  17. 考勤系统的软件上位机设计
  18. java相对路径的写法格式_java相对路径的写法
  19. .net / .net core excel转pdf
  20. 峰瑞资本李丰:共享经济如何改造专业且非标准化的服务业

热门文章

  1. css 导航栏下划线跟随效果,默认第一个li为选中状态
  2. 逃离塔克夫单机版没机器人_逃离塔科夫官网机器人验证通过方法介绍
  3. [20181226]简单探究cluster table.txt
  4. 2023年郑州大学机械考研考情与难度、参考书及上岸前辈备考经验
  5. 《网络营销推广技术、技巧深度解密》文档
  6. 学习笔记-java基础-网络编程
  7. 全媒体运营师胡耀文教你:大规模用户运营体系背后的3大子系统
  8. user-interface vty 0 4 详解
  9. input使用自动输入autofill的时候,修改背景颜色
  10. 中金公司、 汇金公司、 中投公司有什么联系和区别?