码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • [CocosCreator]CocosCreator网络通信:https + websocket + protobuf


    环境

    cocos creator版本:3.8.0

    开发语言:ts

    操作系统:windows

    http部分

    直接使用 XMLHttpRequest 创建http请求

    1. // _getHttpUrl 方法自己写字符串拼接
    2. public httpPostJsonRequest(uri: string, headData: any, data: any, cb: Function) {
    3. let xhr: XMLHttpRequest = new XMLHttpRequest();
    4. xhr.onreadystatechange = () => {
    5. if (xhr.readyState == XMLHttpRequest.DONE) {
    6. if (xhr.status == 200) {// statusText:OK https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/status
    7. let jsonStr: string = xhr.responseText;
    8. console.log('tg post response:', jsonStr);
    9. cb && cb(null, "", jsonStr);
    10. }
    11. }
    12. }
    13. xhr.ontimeout = function (event: ProgressEvent) {
    14. console.log(`http post [${uri}] timeout!`);
    15. cb && cb(event, "Timeout!", "{}");
    16. };
    17. xhr.onerror = (event: ProgressEvent) => {
    18. console.error('XMLHttpRequest error', event);
    19. cb && cb(event, "Request error!", "{}");
    20. }
    21. let url: string = this._getHttpUrl(uri);
    22. xhr.open('POST', url);
    23. xhr.setRequestHeader("Content-type", "application/json");
    24. if (headData) {
    25. for (let k in headData) {
    26. xhr.setRequestHeader(k, headData[k]);
    27. }
    28. }
    29. let json = JSON.stringify(data);
    30. console.log('send http post request:', json);
    31. xhr.send(json);
    32. }
    33. public httpGetRequest(uri: string, headData: any, cb: NetCbFunc) {
    34. let xhr: XMLHttpRequest = new XMLHttpRequest();
    35. xhr.onreadystatechange = () => {
    36. if (xhr.readyState == XMLHttpRequest.DONE) {
    37. if (xhr.status == 200) {// statusText:OK https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/status
    38. let jsonStr: string = xhr.responseText;
    39. console.log('http get response:', jsonStr);
    40. cb && cb(null, '', jsonStr);
    41. }
    42. }
    43. }
    44. xhr.ontimeout = function (event: ProgressEvent) {
    45. console.log('http get request timeout!');
    46. cb && cb(event, "Timeout!", "{}");
    47. };
    48. xhr.onerror = (event: ProgressEvent) => {
    49. console.error('XMLHttpRequest error');
    50. cb && cb(event, "Request error!", "{}");
    51. }
    52. if (headData) {
    53. for (let k in headData) {
    54. xhr.setRequestHeader(k, headData[k]);
    55. }
    56. }
    57. let url: string = this._getHttpUrl(uri);
    58. xhr.open('GET', url);
    59. console.log('send TG get request:', url);
    60. xhr.send();
    61. }
    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
    1. let ws: WebSocket = null;
    2. function connectGameServer() {
    3. ws = new WebSocket("localhost/ws?token=xxxx");
    4. ws.binaryType = "arraybuffer";
    5. ws.onopen = (ev: Event) => {}
    6. ws.onmessage = (ev: MessageEvent) => {
    7. // 解析protobuf
    8. onMessage(ev);
    9. }
    10. ws.onerror = (ev: Event) => {}
    11. ws.onclose = (ev: CloseEvent) => {}
    12. }
    13. function sendWebsocketMessage(buffer: Uint8Array) {
    14. if (ws.readyState === WebSocket.OPEN) {
    15. ws.send(buffer);
    16. }
    17. }
    18. // 发送
    19. function sendRequest(msgId, req) {
    20. // 根据msgId获取到proto对应的类 msgClass
    21. const err = msgClass.verify(req);
    22. if (err) {
    23. console.log('sendRequest error:', err);
    24. return;
    25. }
    26. let obj: ProtoMsgClass = msgClass.create(req);
    27. let writer: protobufjs.Writer = msgClass.encode(obj);
    28. // Uint8Array 和 DataView 需要修改工程目录下的tsconfig.json文件,compilerOptions部分,
    29. // "allowSyntheticDefaultImports": true,
    30. // "target": "ES2019",
    31. // "lib": [ "ES2020", "dom" ]
    32. let messageBuffer: Uint8Array = writer.finish();
    33. // 发送的数据格式需要和服务端对齐,这里的是瞎写的,反正组装成 Uint8Array 数据格式就行
    34. let dv = new DataView(new ArrayBuffer(123));
    35. dv.setInt32(0, messageBuffer.length);
    36. dv.setBigUint64(4, BigInt(msgId));
    37. // 网上找到的这个代码,因为vscode的错误提示改成自己写的一个方法了。
    38. // const targetBuffer = Buffer.concat([new Uint8Array(dv.buffer), messageBuffer])
    39. const targetBuffer = BufferConcat(new Uint8Array(dv.buffer), messageBuffer);
    40. this.sendWebsocketMessage(targetBuffer);
    41. }
    42. public static BufferConcat(buf1: Uint8Array, buf2: Uint8Array): Uint8Array {
    43. let buf: Uint8Array = null;
    44. if (buf1 && buf2) {
    45. let len1 = buf1.length;
    46. let len2 = buf2.length;
    47. buf = new Uint8Array(len1 + len2);
    48. buf.set(buf1);
    49. buf.set(buf2, len1);
    50. }
    51. return buf;
    52. }
    53. // 接收
    54. function onMessage(ev: MessageEvent) {
    55. const binary = new Uint8Array(ev.data);
    56. // 解析格式和服务端对齐就行,123、456、789都是瞎写的
    57. const buf = binary.slice(123, 456);
    58. let view = new DataView(buf.buffer, 0);
    59. const msgId = +view.getBigUint64(0, false).toString();
    60. // 根据msgId获取msgClass
    61. if (msgClass) {
    62. const bodyBuf = binary.slice(789);
    63. const msg = msgClass.decode(bodyBuf);
    64. console.log('onMessage', msg);
    65. // 调用对应回调处理消息
    66. } else {
    67. console.log('onMessage no map class', msgId);
    68. }
    69. }
    参考:
    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
  • 相关阅读:
    【shell 特殊字符】
    【开发备忘】QGroundControl编译
    k8s删除node
    高性能MySQL实战第09讲:如何做到MySQL的高可用?
    Selenium IDE的安装以及使用
    Truenas Scale 安装 Official NextCloud
    猿创征文 第二季| #「笔耕不辍」--生命不息,写作不止#
    Codeforces Round #804 (Div. 2) Editorial(A-B)
    Cmake输出git内容方式
    egret白鹭引擎RES资源管理模块,资源动态加载失效BUG,加载卡死BUG,完整解决方案与超详细调试漏洞过程
  • 原文地址:https://blog.csdn.net/GrimRaider/article/details/140038113
  • 最新文章
  • 【JVM】编译执行与解释执行的区别是什么?JVM 使用哪种方式?
    用 Hashids 优雅解决 C 端自增 ID 暴露问题
    V8引擎 精品漫游指南--Ignition篇(上) 指令 栈帧 槽位 调用约定 内存布局 基础内容
    LLVM Pass快速入门(四):代码插桩
    milkup:桌面端 markdown AI续写和即时渲染
    基于项目工程构建SBOM(软件物料清单)的研究
    鸿蒙应用开发UI基础第二节:鸿蒙应用程序框架核心解析与实操
    .NET 中如何快速实现 List 集合去重?
    扣子Coze实战:从0到1打造抖音+小红书热点监控智能体
    浅谈数据访问层
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号