[CocosCreator]CocosCreator网络通信:https + websocket + protobuf

环境

cocos creator版本:3.8.0

开发语言:ts

操作系统:windows

http部分

直接使用 XMLHttpRequest 创建http请求

// _getHttpUrl 方法自己写字符串拼接public httpPostJsonRequest(uri: string, headData: any, data: any, cb: Function) {let xhr: XMLHttpRequest = new XMLHttpRequest();xhr.onreadystatechange = () => {if (xhr.readyState == XMLHttpRequest.DONE) {if (xhr.status == 200) {// statusText:OK https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/statuslet jsonStr: string = xhr.responseText;console.log('tg post response:', jsonStr);cb && cb(null, "", jsonStr);}}}xhr.ontimeout = function (event: ProgressEvent) {console.log(`http post [${uri}] timeout!`);cb && cb(event, "Timeout!", "{}");};xhr.onerror = (event: ProgressEvent) => {console.error('XMLHttpRequest error', event);cb && cb(event, "Request error!", "{}");}let url: string = this._getHttpUrl(uri);xhr.open('POST', url);xhr.setRequestHeader("Content-type", "application/json");if (headData) {for (let k in headData) {xhr.setRequestHeader(k, headData[k]);}}let json = JSON.stringify(data);console.log('send http post request:', json);xhr.send(json);}public httpGetRequest(uri: string, headData: any, cb: NetCbFunc) {let xhr: XMLHttpRequest = new XMLHttpRequest();xhr.onreadystatechange = () => {if (xhr.readyState == XMLHttpRequest.DONE) {if (xhr.status == 200) {// statusText:OK https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/statuslet jsonStr: string = xhr.responseText;console.log('http get response:', jsonStr);cb && cb(null, '', jsonStr);}}}xhr.ontimeout = function (event: ProgressEvent) {console.log('http get request timeout!');cb && cb(event, "Timeout!", "{}");};xhr.onerror = (event: ProgressEvent) => {console.error('XMLHttpRequest error');cb && cb(event, "Request error!", "{}");}if (headData) {for (let k in headData) {xhr.setRequestHeader(k, headData[k]);}}let url: string = this._getHttpUrl(uri);xhr.open('GET', url);console.log('send TG get request:', url);xhr.send();}
websocket部分

websocket认证:因为ts的websocket不能修改header,所以在创建websocket的url参数里添加params作为Authorization认证数据,例如 let ws = new WebSocket("localhost/ws?token=xxxx");

protobuf部分
安装环境:
  1. protobufjs ^7.3.2:安装命令 npm install --save protobufjs
  2. protobufjs-cli:用于导出proto文件为js/ts,安装命令 npm i -g protobufjs-cli

不安装 protobufjs-cli 也可以,protobufjs可以直接读取proto文件,为了ts编写方便,做了转换。

转换命令(放在package.json的scripts下就行):

  1.     "build-proto:pbjs": "pbjs --dependency protobufjs/minimal.js --target static-module --wrap commonjs --out [导出路径]/proto.js [proto文件路径]/*.proto",

  2. "build-proto:pbts": "pbts --main --out [导出路径]/proto.d.ts [上一步js导出路径]/*.js"

ts代码引用:import proto from '[js导出路径]/proto.js';

多个proto文件都会编入到一个js里。

websocket + protobuf
let ws: WebSocket = null;
function connectGameServer() {ws = new WebSocket("localhost/ws?token=xxxx");ws.binaryType = "arraybuffer";ws.onopen = (ev: Event) => {}ws.onmessage = (ev: MessageEvent) => {// 解析protobufonMessage(ev);}ws.onerror = (ev: Event) => {}ws.onclose = (ev: CloseEvent) => {}
}function sendWebsocketMessage(buffer: Uint8Array) {if (ws.readyState === WebSocket.OPEN) {ws.send(buffer);}
}
// 发送
function sendRequest(msgId, req) {// 根据msgId获取到proto对应的类 msgClassconst err = msgClass.verify(req);if (err) {console.log('sendRequest error:', err);return;}let obj: ProtoMsgClass = msgClass.create(req);let writer: protobufjs.Writer = msgClass.encode(obj);// Uint8Array 和 DataView 需要修改工程目录下的tsconfig.json文件,compilerOptions部分,// "allowSyntheticDefaultImports": true,// "target": "ES2019",// "lib": [ "ES2020",  "dom" ]let messageBuffer: Uint8Array = writer.finish();// 发送的数据格式需要和服务端对齐,这里的是瞎写的,反正组装成 Uint8Array 数据格式就行let dv = new DataView(new ArrayBuffer(123));dv.setInt32(0, messageBuffer.length);dv.setBigUint64(4, BigInt(msgId));// 网上找到的这个代码,因为vscode的错误提示改成自己写的一个方法了。// const targetBuffer = Buffer.concat([new Uint8Array(dv.buffer), messageBuffer])const targetBuffer = BufferConcat(new Uint8Array(dv.buffer), messageBuffer);this.sendWebsocketMessage(targetBuffer);
}public static BufferConcat(buf1: Uint8Array, buf2: Uint8Array): Uint8Array {let buf: Uint8Array = null;if (buf1 && buf2) {let len1 = buf1.length;let len2 = buf2.length;buf = new Uint8Array(len1 + len2);buf.set(buf1);buf.set(buf2, len1);}return buf;}
// 接收
function onMessage(ev: MessageEvent) {const binary = new Uint8Array(ev.data);// 解析格式和服务端对齐就行,123、456、789都是瞎写的const buf = binary.slice(123, 456);let view = new DataView(buf.buffer, 0);const msgId = +view.getBigUint64(0, false).toString();// 根据msgId获取msgClassif (msgClass) {const bodyBuf = binary.slice(789);const msg = msgClass.decode(bodyBuf);console.log('onMessage', msg);// 调用对应回调处理消息} else {console.log('onMessage no map class', msgId);}
}
参考:
  1. websocket进行Authorization验证_websocket authorization-CSDN博客
  2. 前端在WebSocket中加入Token_websocket添加请求头token-CSDN博客
  3. javascript - WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 - Stack Overflow
  4. Essential guide to WebSocket authentication
  5. 8 best WebSocket libraries for Node
  6. 在Javascript中将Uint8Array转换为BigInt-腾讯云开发者社区-腾讯云
  7. websocket创建时附加额外信息 [如自定义headers信息(利用nginx)]_websocket自定义header-CSDN博客
  8. 前端如何在 WebSocket 的请求头中使用标准 HTTP 头携带 Authorization 信息,添加请求头_websocket添加请求头-CSDN博客
  9. JS/TS项目中使用websocket与protobuf_ts protobuf-CSDN博客
  10. TS项目中使用Protobuf的解决方案_protobuf ts-CSDN博客
  11. cocos creator使用protobuf详细方案 - Creator 3.x - Cocos中文社区
  12. cocos creator使用protobuf详细方案 - Creator 3.x - Cocos中文社区
  13. WebSocket 客户端 | Cocos Creator
  14. cocos-test-projects/assets/cases/network/NetworkCtrl.ts at 07f5671e18ef3ed4494d8cba6c2f9499766467a6 · cocos/cocos-test-projects · GitHub
  15. CocosCreator中加入webSocket的使用 - Creator 2.x - Cocos中文社区
  16. Cocos Creator3.8 项目实战(十)使用 protobuf详细教程_cocoscreator protobuf-CSDN博客
  17. 在cocos creator TS 中如何使用protobuf(自动化,评论中有)_cocoscreator ts 面试-CSDN博客
  18. cocos creator中webSocket的使用及封装_cocos onfire-CSDN博客
  19. [CocosCreator]封装WebSocket网络管理器(包含心跳)_cocoscreater socket.io 设置心跳和超时-CSDN博客
  20. https://zhuanlan.zhihu.com/p/653165384
  21. https://zhuanlan.zhihu.com/p/616718383
  22. javascript uint8数组和uint32之间的转换_arcgis unit8转化为unit32-CSDN博客
  23. node.js - How can I fix compile time errors even using compiler options as target es6 and es2017 in Angular 7? - Stack Overflow
  24. WebSocket 的请求头(header)中如何携带 authorization
  25. https://peterolson.github.io/BigInteger.js/BigInteger.min.js
  26. https://github.com/yume-chan/dataview-bigint-polyfill
  27. https://github.com/peterolson/BigInteger.js
  28. CocosCreator与大整数运算库_ts 游戏中大数值怎么计算-CSDN博客
  29. 【分享】自定义arraybuffer数据结构 - Creator 2.x - Cocos中文社区
  30. DataView - JavaScript | MDN
  31. ES6,Number类型和新增的BigInt数据类型,以及数值精度丢失的问题_es6除号-CSDN博客
  32. CocosCreator 源码./polyfill/array-buffer详解 - 简书
  33. [ts]typescript高阶之typeof使用_ts typeof-CSDN博客
  34. TypeScript 【type】关键字的进阶使用方式_typescript type使用-CSDN博客
  35. 记录JS XMLHttpRequest POST提交JSON数据的格式_xmlrequest post json-CSDN博客
  36. JS使用XMLHttpRequest对象POST收发JSON格式数据_js发送json-CSDN博客
  37. https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

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

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

相关文章

2024年6月大众点评深圳餐饮店铺POI分析18万家

2024年6月大众点评深圳餐饮店铺POI共有178720家 店铺POI点位示例: 店铺id G9TSD2JvdLtA7fdm 店铺名称 江味龙虾馆(南山店) 十分制服务评分 8.8 十分制环境评分 8.8 十分制划算评分 8.6 人均价格 128 评价数量 12840 店铺地址 南山大道与桂庙路交叉口西北角…

微信小程序 点击左上角返回弹窗提示

业务需求:当页面表单没有提交直接返回时,要提示用户是否保存当前信息,如果已经提交就不提示了。 由于微信小程序是无法监听右上角按钮返回事件。 所以就换个思路 小程序提供了如下两个Api wx.enableAlertBeforeUnload(Object object)&…

Python入门-基础知识-编程规范

1.缩进 在编程语言中,代码之间往往存在着一定的逻辑关系和层次关系。C语言和Java语言等 用“{}”分隔代码块,而Python用的是缩进和冒号。Python代码的缩进可以使用空格键或 Tab键来实现,通常情况下以4个空格或1个制表符作为1个缩进量。Pytho…

TCP协议中的三次握手和四次挥手机制

TCP协议中的三次握手和四次挥手机制 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,它的三次握手和四次挥手机制是建立和断开连接的关键步骤。 三次握手: 第一次…

等保测评与网络安全法规的关联:构建信息安全的法律与技术双重保障

在信息化高速发展的今天,网络安全已经成为国家安全、社会稳定和经济发展的重要基石。为了保障网络空间的安全和稳定,我国制定了一系列网络安全法规,其中最为关键的就是《中华人民共和国网络安全法》。与此同时,等保测评&#xff0…

第 2 章SwiftUI 入门及文本操作

如果你之前使用过 UIKit,你会发现TextSwiftUI 中的控件与 UIKit 中的非常相似UILabel。它是一个允许你显示一行或多行文本的视图。此Text控件不可编辑,但可用于在屏幕上显示只读信息。例如,如果你想显示一条屏幕消息,你可以使用它Text来实现它。 在本章中,我们将向您展示…

RAG开发中常见的12个痛点及解决方案

受到 Barnett 等人论文《构建检索增强生成系统的七大挑战》启发,本文将探讨论文中提及的七大挑战及在开发 RAG(检索增强生成)流程中常遇到的五个额外难题。更为重要的是,我们将深入讨论解决这些 RAG 难题的策略,以便我…

使用 WebGL 创建 3D 对象

WebGL Demohttps://mdn.github.io/dom-examples/webgl-examples/tutorial/sample5/index.html 现在让我们给之前的正方形添加五个面从而可以创建一个三维的立方体。最简单的方式就是通过调用方法 gl.drawElements() 使用顶点数组列表来替换之前的通过方法gl.drawArrays() 直接…

TinTin Web3 动态精选:Aptos Builder Jam 亚洲首站即将开启,Solana 实现全网连接

TinTin 快讯由 TinTinLand 开发者技术社区打造,旨在为开发者提供最新的 Web3 新闻、市场时讯和技术更新。TinTin 快讯将以周为单位, 汇集当周内的行业热点并以快讯的形式排列成文。掌握一手的技术资讯和市场动态,将有助于 TinTinLand 社区的开…

检测SD NAND文件系统异常和修复的方法

目录 1、打开命令提示符: 2、运行chkdsk命令: 3、命令参数说明: chkdsk是Windows中的一个命令行工具,用于检查磁盘上的文件系统错误和修复坏块。MK米客方德为您提供指导,以下是使用chkdsk的步骤: 1、打开…

综合IT运维管理解决方案

综合IT运维管理解决方案 在信息化和数字化高速发展的时代,企业的IT运维管理已经成为保障业务连续性和提升运营效率的关键环节。高效的IT运维管理不仅能够降低运维成本,还能提升服务质量和用户满意度。本文将详细介绍综合IT运维管理解决方案,…

富格林:正规平台曝光出金招数

富格林悉知,在现货黄金中,正规盈利出金是要建立在无落入诱导风险的情况下实现的,投资者要关注的不仅仅是如何进行盈利,还要掌握正规平台曝光的交易技巧或经验。对于新手投资者来说,学习投资的基础知识,提升…

eBPF技术揭秘:DeepFlow如何引领故障排查,提升运维效率

DeepFlow 实战:eBPF 技术如何提升故障排查效率 目录 DeepFlow 实战:eBPF 技术如何提升故障排查效率 微服务架构系统中各个服务、组件及其相互关系的全景 零侵扰分布式追踪(Distributed Tracing)的架构和工作流程 关于零侵扰持…

华为od 2024 | 什么是华为od,od 薪资待遇,od机试题清单

目录 专栏导读华为OD机试算法题太多了,知识点繁杂,如何刷题更有效率呢? 一、逻辑分析二、数据结构1、线性表① 数组② 双指针 2、map与list3、队列4、链表5、栈6、滑动窗口7、二叉树8、并查集9、矩阵 三、算法1、基础算法① 贪心思维② 二分查…

后端系统的安全性

后端系统的安全性 后端系统的安全性是任何Web应用或服务的核心组成部分,它涉及保护数据、用户隐私以及系统免受恶意攻击。以下是后端安全的一些关键点: 认证和授权:确保只有经过身份验证的用户才能访问特定资源。这通常包括使用用户名/密码…

Spring Session将HttpSession保存到Redis中,实现重启应用会话不丢失

这篇文章介绍一下在springboot项目中整合Spring Session,将session会话信息保存到Redis中,防止重启应用导致会话丢失。 第一步 创建一个springboot项目,添加spring-session-redis的依赖,因为要用到reids,所以要把redi…

扩散模型中的UNET

目录 一、为什么UNET模型可以用于去噪网络二、扩散模型中的UNET是一个条件去噪网络,怎么实现的三、UNET用于分割和用去去噪的区别 一、为什么UNET模型可以用于去噪网络 下采样部分: 能够提取图像的深层次特征,这些特征往往包含图像的重要结构和信息&…

Python 继承:理解与应用

Python中的继承是面向对象编程中重要的概念之一,允许一个类(子类)从另一个类(父类)继承属性和方法。这种机制不仅能提高代码的重用性,还有助于构建层次化的数据模型,简化复杂系统的设计与维护。…

原型开发:加速需求验证与设计优化

目录 前言1. 原型开发的意义1.1 定义与概述1.2 原型的类型 2. 原型开发的优势2.1 明确需求2.2 提升用户满意度2.3 降低开发风险 3. 原型开发的挑战3.1 过多的原型开发3.2 资源投入与管理3.3 期望管理 4. 优化原型开发流程4.1 明确目标与范围4.2 选择合适的工具和方法4.3 加强用…

【MySQL基础篇】概述及SQL指令:DDL及DML

数据库是一个按照数据结构来组织、存储和管理数据的仓库。以下是对数据库概念的详细解释:定义与基本概念: 数据库是长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。 数据库不仅仅是数据的简单堆积,而是遵循一定的规则…