cocos creator版本:3.8.0
开发语言:ts
操作系统:windows
直接使用 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/status
- let 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/status
- let 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认证:因为ts的websocket不能修改header,所以在创建websocket的url参数里添加params作为Authorization认证数据,例如 let ws = new WebSocket("localhost/ws?token=xxxx");
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里。
- let ws: WebSocket = null;
- function connectGameServer() {
- ws = new WebSocket("localhost/ws?token=xxxx");
- ws.binaryType = "arraybuffer";
- ws.onopen = (ev: Event) => {}
- ws.onmessage = (ev: MessageEvent) => {
- // 解析protobuf
- onMessage(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对应的类 msgClass
- const 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获取msgClass
- if (msgClass) {
- const bodyBuf = binary.slice(789);
- const msg = msgClass.decode(bodyBuf);
- console.log('onMessage', msg);
- // 调用对应回调处理消息
- } else {
- console.log('onMessage no map class', msgId);
- }
- }