官方网站模版长春电商网站建设价格

当前位置: 首页 > news >正文

官方网站模版,长春电商网站建设价格,专业做网站路桥,注册安全工程师报考条件及科目前言 故事背景 简单说下背景#xff0c;项目中需要用 ProtoBuf 协议转换请求参数#xff0c;并通过 WebSocket 进行双向通信。重点#xff01;一个是 web端#xff08;Vue3 TS#xff09;#xff0c;一个是微信小程序端#xff08;原生 JS#xff09;。 剧情发展 …前言 故事背景 简单说下背景项目中需要用 ProtoBuf 协议转换请求参数并通过 WebSocket 进行双向通信。重点一个是 web端Vue3 TS一个是微信小程序端原生 JS。 剧情发展 一开始web端通过 ts-proto 这个库进行开发问题倒是不大。将跑通的这部分代码进行 ts 转 js 之后挪用到微信小程序端的时候奇奇怪怪的问题就出现了。 灵异事件一 问题描述 问题1 发送文本消息电脑上正常手机上直接发送失败 问题描述 发送文本消息的情况在电脑上也就是微信开发者工具中的 模拟器 上是可以正常通信的但是在手机上也就是预览的时候发送文本是直接无法发送 报错提示大致意思就是方法执行失败可以很容易定位到在数据转换encode的这个过程有问题 。 问题截图 1电脑端 - 正确 2手机端 - 报错 问题2发送语音消息电脑能发但是服务端解析失败手机上直接就发不了 问题描述 最离谱也是最坑的事件来了。 当电脑端发送语音消息的时候WS可以正常来回通信但是服务端拿到的语音数据解析异常导致语音文本识别失败并且这段语音数据生成的url是无法播放的。 当手机端发送语音消息的时候表现就和上面的发送文本消息一样直接发送不出去这个倒是可以接受可以直接定位到前端数据转换encode的过程有问题。 问题截图 1电脑端 - 发送成功但是服务端获取到的语音数据是异常的导致语音转文本失败 2手机端 - 报错 解决方案 1、分析原因 通过在项目中 断点调试或者 console.log 的方法可以很快定位到是 proto 文件生成的 JS 文件中的变量方法 encode 在小程序端无效。注意这个方法在浏览器web页面上是可行的所以大概率是由于宿主环境不同导致转编译方法的一些内部依赖无效。毕竟web端用的第三方库主要是针对浏览器环境的并没有明确说支持微信端 。 回顾一下 web端项目引用的第三方库是 TS 版本的 protobuf —— ts-proto 那么以上的那个推测原因就更有可能了。 所以第一步在小程序端重新引用 JS 版本的 protobuf —— protobufjs 2、npm包介绍 这部分是最精彩的部分所以单独拎出来作为第二步讲解。 当我们用 protobufjs 这个库的时候需要两样东西一个是代码中需要引用的 protobuf 本人一个是用来转换 xxx.proto 文件用的脚本命令 pbjs 也就是我下面截图中提到的 protobufjs-cli 当我们打开 protobufjs 这个使用教程的时候会看到下面这个安装指引。 这里需要重点说明一下之前只要执行 npm install protobufjs –save 这端安装脚本之后就可以使用 pbjs 命令的但是改了一切都变了请看官方说明—— pbjs-for-javascript 这里重点吐槽一下上面截图中的 its own package 点过去还是个404页面所以这里我们只能通过 protobufjs 在安装指引中提到的 protobufjs-cli 联想推测应该指的就是这个库了 3、具体步骤 综上所述你要做的就是 步骤一安装 npm 包 在你的微信小程序项目中终端打开执行命令如下 npm install protobufjs –save打开你的电脑终端这里我以mac为例执行命令如下 sudo npm install -g protobufjs-cli安装完之后可以执行一下 pbjs 是否可用正常输出如下
步骤二转换 proto 文件为 js 文件 通过上面安装的库我们继续使用 pbjs 命令来生成 xxx.proto 对应的 JS文件例如我这个项目使用的命令如下 pbjs -t static-module -w commonjs -o ./protobuf/proto/base.js ./protobuf/proto/base.proto上面这行命令你要改的就是把 输入、输出的文件路径 改成自己项目的路径即可。具体的参数介绍务必去官网 pbjs-for-javascript 学习了解一下知其然知其所以然 步骤三修改生成的 xxx.js 文件 通过 pbjs 生成的 JS文件 还没完事还需要再改一下这份 JS文件 内部的一行代码具体如下
步骤四使用生成的 xxx.js 文件 在我们的业务代码中使用通过 pbjs 生成的 JS文件 具体细节如下 1、导入 protobuf 的方法 2、使用 protobuf 实例对象中的属性与方法encode、decode这些
3、本来这部分是要放到 灵异事件2 去讲解引出的为了确保上下文的完整性这里直接交代结果了。
关键代码 const xxxArrayBuffer Uint8Array.from(xxxUint8Array).buffer;重点说明 因为我们用的 protobuf 这个库是通过 Uint8Array 进行 encode 和 decode 等一些列操作的但是微信小程序 WebSocket通信 并不支持 Uint8Array 数据所以我们需要在发起请求之前对数据进行一个转换处理——将 Uint8Array 转成普通的 ArrayBuffer ! 截止目前问题已经解决。下文将继续分享解决过程中遇到的问题以及涉及到的知识点、参考资料。 灵异事件二 这里让我们回到上面 解决方案 / 具体步骤 / 步骤四使用生成的 xxx.js 文件 当我们通过网上教程正确安装并使用 protobufjs 时发现离谱的事情又来了 问题描述 简言之就是电脑上可以手机上不行。 问题1 发送文本消息的时候电脑端的模拟器上是可行的一切都正常手机端发送 websocket 请求时报错大致意思是不支持的数据类型fail invalid data type。 问题2 发送语音消息的时候电脑端的模拟器上是 半可行的 注意这是最坑爹的因为这个表现直接误导了问题定位方向 。所谓的 半可行的 就是和上面的 灵异事件一/ 问题2发送语音消息电脑能发但是服务端解析失败手机上直接就发不了 一样电脑端的模拟器上表现请求是发出去了但是服务端获取到的语音数据是异常的无法播放、无法识别语音文本内容。手机端表现和上面的问题1一致也是 websocket 请求失败fail invalid data type。 问题截图 1电脑端 - 发送文本成功截图如下 2手机端 - websocket 请求失败截图如下 解决方案 上文中已经交代过了所以这里知识将上面的内容复制粘贴了一下不介意的话可以再看一遍。 本来这部分是要放到 灵异事件2 去讲解引出的为了确保上下文的完整性 这里直接交代结果了。
关键代码 const xxxArrayBuffer Uint8Array.from(xxxUint8Array).buffer;重点说明 因为我们用的 protobuf 这个库是通过 Uint8Array 进行 encode 和 decode 等一些列操作的但是微信小程序 WebSocket通信 并不支持 Uint8Array 数据所以我们需要在发起请求之前对数据进行一个转换处理——将 Uint8Array 转成普通的 ArrayBuffer ! 知识点 1、ArrayBuffer、Uint8Array 定义 ArrayBuffer 和 Uint8Array 是 JavaScript 中用于处理二进制数据的两种不同类型的数据结构。 关系 Uint8Array是一种TypedArray类型化数组它是基于ArrayBuffer对象来构建的。ArrayBuffer是一个数据存储区表示一段固定长度的二进制数据而Uint8Array提供了一种视图用于以特定的格式在Uint8Array的情况下是无符号 8 位整数来访问和操作ArrayBuffer中的数据。 简单地说ArrayBuffer是底层的数据存储Uint8Array是操作和访问这些存储数据的一种方式可以将ArrayBuffer看作是一块内存区域而Uint8Array则是在这块内存区域上的一种数据解析和操作工具。 区别 1、操作数据的方式 ArrayBuffer 由于ArrayBuffer本身没有操作数据的方法所以不能直接对其存储的数据进行读写操作。如果要操作ArrayBuffer中的数据必须通过视图如Uint8Array等类型化数组视图或者DataView来进行。 Uint8Array Uint8Array提供了丰富的数组方法来操作数据因为它将数据视为数组。例如可以使用索引来访问和修改元素像uint8Array[0] 25;这样的操作就可以将Uint8Array视图中的第一个元素对应ArrayBuffer中的第一个字节设置为 25。同时它还支持数组的遍历方法如forEach、map等。 2、用途 ArrayBuffer 常用于在底层存储二进制数据比如从网络接收的文件数据、图像数据、音频数据等原始字节流。它是一种通用的、原始的数据存储机制在涉及到与外部数据源进行二进制数据交互时非常有用。 Uint8Array 适合处理字节级别的数据比如对二进制数据进行按字节的操作、解析简单的二进制协议等。因为它将数据视为无符号 8 位整数数组所以在处理字节操作频繁的场景如加密算法中的字节处理、简单的文件格式解析等下更加方便和直观。 2、Protobuf 定义 Protocol Buffers简称 Protobuf是 Google 开发的一种数据序列化格式用于将结构化数据序列化和反序列化。它类似于XML或JSON但更小、更快、也更简单。Protobuf的设计初衷是为了解决通信协议和数据存储格式的问题使得在多种编程语言之间高效地交换结构化数据成为可能。 数据格式特点 1、高效性 空间效率高 Protobuf 序列化后的数据格式紧凑相比其他文本格式如 XML、JSON在存储和传输时占用更少的空间。例如对于包含相同信息的整数、字符串等数据Protobuf 序列化后的字节数通常远小于 JSON 格式。 时间效率高 序列化和反序列化速度快因为 Protobuf 使用了二进制格式并且对数据的编码和解码进行了优化。在处理大量数据时其性能优势尤为明显。 2、跨语言和平台支持 Protobuf 支持多种编程语言包括但不限于 Java、C、Python、Go、JavaScript 等。这意味着在一个用 Java 编写的服务端程序中序列化的数据可以在一个用 Python 编写的客户端程序中准确地反序列化出来只要它们使用的 Protobuf 消息定义是一致的。 可以在不同的操作系统如 Windows、Linux、macOS和硬件平台上实现无缝的数据交换。 3、可扩展性和兼容性 向前兼容 当对已有的数据结构进行扩展如添加新的字段时老版本的程序仍然能够正确地读取和处理大部分数据不会因为新字段的添加而完全失效。 向后兼容 新的程序也能够读取和处理老版本数据结构序列化的数据忽略新增字段即可。这种兼容性使得在分布式系统和长期运行的项目中升级数据结构变得更加容易。 使用流程 定义消息类型 在 .proto 文件中定义数据结构的消息类型如上面的 Person 消息。 生成代码 使用 Protobuf 编译器不同语言有各自的编译器插件根据 .proto 文件生成对应语言的代码。例如对于 Java 语言会生成包含 Person 类的代码这个类中包含了对消息中各个字段的访问和操作方法。 序列化和反序列化数据 在程序中使用生成的代码创建消息对象填充数据后进行序列化然后可以将序列化的数据传输或存储。接收方获取到数据后使用相同的代码进行反序列化恢复出原始的数据结构。 参考资料 protobufjsts-protopbjs-for-javascriptLanguage Guide (proto 3)如何在前端中使用protobufvue篇微信小程序使用protobuf小程序websocket 通讯 发送 protobuf数据 Uint8Array 异常 最后 以上内容主要是介绍了 在微信小程序端通过 WebSocket 用 Protobuf 协议进行前后端通信的解决方案。 其实在整个项目背景下实现语音聊天功能实际上还涉及到很多较为复杂的微信小程序 API 操作 录音功能WebSocket 任务读取本地文件 关于微信小程序接口的注意事项 1、注意录音格式 直接上代码仅供参考 recorderManager.start({// 采样率pc不支持sampleRate: 16000,// 编码码率默认就是 48000encodeBitRate: 48000,// 音频格式默认是 aac)format: wav,success: () {// do sth.} });文档地址 RecorderManager.start 关键参数介绍
2、注意读取本地文件的编码格式 这是清理后的伪代码仅供参考 /** 录音结束后的回调函数 */ function recorderOnStopHandler(res) {const { tempFilePath, duration } res;const { friendUserId } this.data;// 发送 WS 请求语音消息const fs wx.getFileSystemManager();fs.readFile({filePath: tempFilePath,// encoding: 指定读取文件的字符编码如果不传 encoding则以 ArrayBuffer 格式读取文件的二进制内容// encoding 不要设置默认就是 ArrayBuffer// encoding: binary, ———— 不要用这个success: (res) {// 读取完成后res.data 包含文件内容的二进制字符串const arrayBuffer res.data;// 转成 protobuf 需要的 uint8Arrayconst uint8Array new Uint8Array(arrayBuffer);// 创建消息对象const payload {friendUserId: friendUserId,duration: duration,audio: uint8Array};// 序列化消息const paramsU8Array ChatAudioParams.encode(payload).finish();// 这里还不能直接发送 - 需要转成 arraybuff// this.wsSend(buffer2);// 微信小程序的通信数据不支持 Uint8Array Uint8Array 转出 arraybuffconst paramsBuffer Uint8Array.from(paramsU8Array).buffer;// 发送 buffer 到服务器this.wsSend(paramsBuffer);},fail: (err) {console.error(读取文件失败, err);}}); }文档地址 FileSystemManager.readFile 关键参数介绍 3、关于微信开发者工具的坑 上文虽然解决了 实际问题 但是 微信开发者工具 的 模拟器 上发语音还是有问题发送文本是正常的但是发送语音的音频数据异常服务端无法识别语音内容同时这段音频在电脑上是可以播放的但是手机上无法播放。大致原因就是电脑端模拟器上音频数据在 encode 之后的数据格式异常 END.