環境
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