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

[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.lryc.cn/news/388971.html

相关文章:

  • 并发控制-事务的调度、数据不一致问题(更新丢失、脏读、不可重复读)、非串行调度的的可串行化
  • Golang | Leetcode Golang题解之第202题快乐数
  • 算法:哈希表
  • 自然语言处理基本知识(1)
  • Java中的数据加密与安全传输
  • UG NX二次开发(C++)-根据草图创建拉伸特征(UFun+NXOpen)
  • TS_开发一个项目
  • 2024年华为OD机试真题-传递悄悄话 -C++-OD统一考试(C卷D卷)
  • eclipse基础工程配置( tomcat配置JRE环境)
  • Spring Boot 学习第八天:AOP代理机制对性能的影响
  • Linux[高级管理]——Squid代理服务器的部署和应用(传统模式详解)
  • 使用Vue 2 + Element UI搭建后台管理系统框架实战教程
  • Carla安装教程
  • 【PYG】处理Cora数据集分类任务使用的几个函数log_softmax,nll_loss和argmax
  • Labview绘制柱状图
  • 使用Python实现一个简单的密码管理器
  • 【云原生】服务网格(Istio)如何简化微服务通信
  • spring boot 整合 sentinel
  • 蜜雪冰城小程序逆向
  • pbootcms提交留言成功后跳转到指定的网址
  • 16、matlab求导、求偏导、求定积分、不定积分、数值积分和数值二重积分
  • MySQL 9.0创新版发布!功能又进化了!
  • 后端系统的安全性
  • .net 百度翻译接口核心类
  • 安卓应用开发学习:通过腾讯地图SDK实现定位功能
  • iptable精讲
  • 2024 年如何构建 AI 软件
  • Python实战,桌面小游戏,剪刀石头布
  • Hadoop权威指南-读书笔记-01-初识Hadoop
  • HttpServletResponse设置headers返回,发现headers中缺少“Content-Length“和“Content-Type“两个参数。