[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部分
安装环境:
- protobufjs ^7.3.2:安装命令 npm install --save protobufjs
-
protobufjs-cli:用于导出proto文件为js/ts,安装命令 npm i -g protobufjs-cli
不安装 protobufjs-cli 也可以,protobufjs可以直接读取proto文件,为了ts编写方便,做了转换。
转换命令(放在package.json的scripts下就行):
-
"build-proto:pbjs": "pbjs --dependency protobufjs/minimal.js --target static-module --wrap commonjs --out [导出路径]/proto.js [proto文件路径]/*.proto",
-
"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);}
}
参考:
- websocket进行Authorization验证_websocket authorization-CSDN博客
- 前端在WebSocket中加入Token_websocket添加请求头token-CSDN博客
- javascript - WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 - Stack Overflow
- Essential guide to WebSocket authentication
- 8 best WebSocket libraries for Node
- 在Javascript中将Uint8Array转换为BigInt-腾讯云开发者社区-腾讯云
- websocket创建时附加额外信息 [如自定义headers信息(利用nginx)]_websocket自定义header-CSDN博客
- 前端如何在 WebSocket 的请求头中使用标准 HTTP 头携带 Authorization 信息,添加请求头_websocket添加请求头-CSDN博客
- JS/TS项目中使用websocket与protobuf_ts protobuf-CSDN博客
- TS项目中使用Protobuf的解决方案_protobuf ts-CSDN博客
- cocos creator使用protobuf详细方案 - Creator 3.x - Cocos中文社区
- cocos creator使用protobuf详细方案 - Creator 3.x - Cocos中文社区
- WebSocket 客户端 | Cocos Creator
- cocos-test-projects/assets/cases/network/NetworkCtrl.ts at 07f5671e18ef3ed4494d8cba6c2f9499766467a6 · cocos/cocos-test-projects · GitHub
- CocosCreator中加入webSocket的使用 - Creator 2.x - Cocos中文社区
- Cocos Creator3.8 项目实战(十)使用 protobuf详细教程_cocoscreator protobuf-CSDN博客
- 在cocos creator TS 中如何使用protobuf(自动化,评论中有)_cocoscreator ts 面试-CSDN博客
- cocos creator中webSocket的使用及封装_cocos onfire-CSDN博客
- [CocosCreator]封装WebSocket网络管理器(包含心跳)_cocoscreater socket.io 设置心跳和超时-CSDN博客
- https://zhuanlan.zhihu.com/p/653165384
- https://zhuanlan.zhihu.com/p/616718383
- javascript uint8数组和uint32之间的转换_arcgis unit8转化为unit32-CSDN博客
- node.js - How can I fix compile time errors even using compiler options as target es6 and es2017 in Angular 7? - Stack Overflow
- WebSocket 的请求头(header)中如何携带 authorization
- https://peterolson.github.io/BigInteger.js/BigInteger.min.js
- https://github.com/yume-chan/dataview-bigint-polyfill
- https://github.com/peterolson/BigInteger.js
- CocosCreator与大整数运算库_ts 游戏中大数值怎么计算-CSDN博客
- 【分享】自定义arraybuffer数据结构 - Creator 2.x - Cocos中文社区
- DataView - JavaScript | MDN
- ES6,Number类型和新增的BigInt数据类型,以及数值精度丢失的问题_es6除号-CSDN博客
- CocosCreator 源码./polyfill/array-buffer详解 - 简书
- [ts]typescript高阶之typeof使用_ts typeof-CSDN博客
- TypeScript 【type】关键字的进阶使用方式_typescript type使用-CSDN博客
- 记录JS XMLHttpRequest POST提交JSON数据的格式_xmlrequest post json-CSDN博客
- JS使用XMLHttpRequest对象POST收发JSON格式数据_js发送json-CSDN博客
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
相关文章:
[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…...
并发控制-事务的调度、数据不一致问题(更新丢失、脏读、不可重复读)、非串行调度的的可串行化
一、引言 1、数据库管理系统DBMS的事务处理技术实现的另一个主要功能部分是并发控制机制。并发控制机制完成的功能就是对并发执行的事务进行控制,保证事务的隔离性,从而进一步保持数据库的一致性。 2、事务的并发控制就是对并发执行的不同事务中的数据…...
Golang | Leetcode Golang题解之第202题快乐数
题目: 题解: func isHappy(n int) bool {cycle : map[int]bool{4: true, 6: true, 37: true, 58: true, 89: true, 145: true, 42: true, 20: true}for n ! 1 && !cycle[n] {n step(n)}return n 1 }func step(n int) int {sum : 0for n > …...
算法:哈希表
目录 题目一:两数之和 题目二:判定是否互为字符重排 题目三:存在重复元素I 题目四:存在重复元素II 题目五:字母异位词分组 关于哈希表 哈希表就是存储数据的容器 哈希表的优势是:快速查找某个元素O(…...
自然语言处理基本知识(1)
一 分词基础 NLP:搭建了计算机语言和人类语言之间的转换 1 精确分词,试图将句子最精确的分开,适合文本分析 >>> import jieba >>> content "工信处女干事每月经过下属科室" >>> jieba.cut(content,cut_all …...
Java中的数据加密与安全传输
Java中的数据加密与安全传输 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来探讨一下在Java中如何实现数据加密与安全传输。 随着互联网的普及和网络…...
UG NX二次开发(C++)-根据草图创建拉伸特征(UFun+NXOpen)
1、前言 UG NX是基于特征的三维建模软件,其中拉伸特征是一个很重要的特征,有读者问如何根据草图创建拉伸特征,我在这篇博客中讲述一下草图创建拉伸特征的UG NX二次开发方法,感兴趣的可以加入QQ群:749492565,或者在评论区留言。 2、在UG NX中创建草图,然后创建拉伸特征 …...
TS_开发一个项目
目录 一、编译一个TS文件 1.安装TypeScript 2.创建TS文件 3.编译文件 4.用Webpack打包TS ①下载依赖 ②创建文件 ③启动项目 TypeScript是微软开发的一个开源的编程语言,通过在JavaScript的基础上添加静态类型定义构建而成。TypeScript通过TypeScript编译器或…...
2024年华为OD机试真题-传递悄悄话 -C++-OD统一考试(C卷D卷)
2024年OD统一考试(D卷)完整题库:华为OD机试2024年最新题库(Python、JAVA、C++合集) 题目描述: 给定一个二叉树,每个节点上站着一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。 初始时,根节点所在位置的人有一个悄悄话想要传递给其他人,求二叉树所有节…...
eclipse基础工程配置( tomcat配置JRE环境)
文章目录 I eclipse1.1 工程配置1.2 编译工程1.3 添加 JRE for the project build pathII tomcat配置JRE环境2.1 Eclipse编辑tomcat运行环境(Mac版本)2.2 Eclipse编辑tomcat运行环境(windows版本)2.3 通过tomcat7W.exe配置运行环境(windows系统)I eclipse 1.1 工程配置 …...
Spring Boot 学习第八天:AOP代理机制对性能的影响
1 概述 在讨论动态代理机制时,一个不可避免的话题是性能。无论采用JDK动态代理还是CGLIB动态代理,本质上都是在原有目标对象上进行了封装和转换,这个过程需要消耗资源和性能。而JDK和CGLIB动态代理的内部实现过程本身也存在很大差异。下面将讨…...
Linux[高级管理]——Squid代理服务器的部署和应用(传统模式详解)
🏡作者主页:点击! 👨💻Linux高级管理专栏:点击! ⏰️创作时间:2024年6月24日11点11分 🀄️文章质量:95分 目录 ————前言———— Squid功能 Squ…...
使用Vue 2 + Element UI搭建后台管理系统框架实战教程
后台管理系统作为企业内部的核心业务平台,其界面的易用性和功能性至关重要。Vue 2作为一个成熟的前端框架,以其轻量级和高效著称,而Element UI则是一套专为桌面端设计的Vue 2组件库,它提供了丰富的UI元素和组件,大大简…...
Carla安装教程
1.前言 对于从事自动驾驶的小伙伴而言,或多或少应该都接触过一些的仿真软件,今天要给大家介绍的这款仿真软件应该算的上是业界非常有名的一款仿真软件——carla。 目前carla的学习教程也还是蛮多的,但是写的都不是很全,在配置的…...
【PYG】处理Cora数据集分类任务使用的几个函数log_softmax,nll_loss和argmax
文章目录 log_softmax解释作用示例解释输出 nll_loss解释具体操作示例代码解释 nll_losslog_softmaxcross_entropy解释代码示例解释 argmax()解释作用示例代码解释示例输出 log_softmax F.log_softmax(x, dim1) 是 PyTorch 中的一个函数,用于对输入张量 x 应用 log…...
Labview绘制柱状图
废话不多说,直接上图 我喜欢用NXG风格,这里我个人选的是xy图。 点击箭头指的地方 选择直方图 插值选择第一个 直方图类型我选的是第二个效果如图。 程序部分如图。 最后吐槽一句,现在看CSDN好多文章都要收费了,哪怕一些简单的入…...
使用Python实现一个简单的密码管理器
文章目录 一、项目概述二、实现步骤2.1 安装必要的库2.2 设计密码数据结构2.3 实现密码加密和解密2.4 实现主要功能2.4.1 添加新密码2.4.2 显示所有密码2.4.3 查找特定密码2.4.4 更新密码2.4.5 删除密码 2.5 实现用户界面 三、代码示例3.1 加密和解密示例3.2 用户界面示例 在现…...
【云原生】服务网格(Istio)如何简化微服务通信
🐇明明跟你说过:个人主页 🏅个人专栏:《未来已来:云原生之旅》🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、微服务架构的兴起 2、Istio:服务网格的佼…...
spring boot 整合 sentinel
注意版本问题 我这是jdk11 、spring boot 2.7.15 、 alibaba-sentinel 2.1.2.RELEASE <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.15</version><…...
蜜雪冰城小程序逆向
app和小程序算法一样 小程序是wasm...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...
Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...
