拆分网络模块

This commit is contained in:
gongxh 2025-06-08 15:30:12 +08:00
parent 6953f738b0
commit 5b5e4b5936
17 changed files with 24 additions and 894 deletions

View File

@ -42,3 +42,7 @@
## 1.1.4 事件模块拆分
- 拆分事件模块,使用 `npm install kunpocc-event` 安装
* 仓库地址: https://github.com/Gongxh0901/kunpocc-event
## 1.1.5 网络模块拆分
- 拆分网络模块,使用 `npm install kunpocc-net` 安装
* 仓库地址: https://github.com/Gongxh0901/kunpocc-net

View File

@ -37,25 +37,23 @@ npm set registry https://npm.aliyun.com
# 目录
1. [使用教程 (新手必看)](./docs/Noviciate.md)
2. [项目配置](./docs/Basic.md)
3. [UI模块](./docs/UI.md)
4. [ec模块](https://github.com/Gongxh0901/kunpo-ec)
5. [ecs模块](https://github.com/Gongxh0901/kunpo-esc)
6. [网络模块](./docs/HTTP.md)
7. [四叉树](https://github.com/Gongxh0901/kunpo-quadtree)
8. [行为树](https://github.com/Gongxh0901/kunpocc-behaviortree)
9. [资源管理](https://github.com/Gongxh0901/kunpocc-assets)
10. [条件显示节点 (一般用于UI上的红点)](./docs/Condition.md)
11. [全局事件](./docs/Event.md)
12. [全局计时器](./docs/Timer.md)
13. [平台工具](./docs/Platform.md)
14. [屏幕尺寸](./docs/Screen.md)
15. [小工具](./docs/Tools.md)
16. [时间](./docs/Time.md)
17. [socket网络模块](./docs/Socket.md)
18. [小游戏接口封装](./docs/MiniGame.md)
19. [热更新](./docs/HotUpdate.md)
5. [全局计时器](./docs/Timer.md)
6. [平台工具](./docs/Platform.md)
7. [屏幕尺寸](./docs/Screen.md)
8. [小工具](./docs/Tools.md)
9. [时间](./docs/Time.md)
10. [小游戏接口封装](./docs/MiniGame.md)
11. [热更新](./docs/HotUpdate.md)
12. [条件显示节点 (一般用于UI上的红点)](./docs/Condition.md)
13. [ec模块](https://github.com/Gongxh0901/kunpo-ec)
14. [ecs模块](https://github.com/Gongxh0901/kunpo-esc)
15. [网络模块 http和socket](https://github.com/Gongxh0901/kunpocc-net)
16. [四叉树](https://github.com/Gongxh0901/kunpo-quadtree)
17. [行为树](https://github.com/Gongxh0901/kunpocc-behaviortree)
18. [资源管理](https://github.com/Gongxh0901/kunpocc-assets)
19. [全局事件](https://github.com/Gongxh0901/kunpocc-event)
## 类型支持
该库完全使用 TypeScript 编写,提供完整的类型定义文件。

View File

@ -1,32 +0,0 @@
## 全局事件系统
### 使用
```typescript
import { GlobalEvent } from 'kunpocc';
// 添加事件监听
GlobalEvent.add('eventName', (arg1, arg2) => {
console.log('事件触发:', arg1, arg2);
}, this);
// 添加一次性事件监听
GlobalEvent.addOnce('oneTimeEvent', (data) => {
console.log('一次性事件触发:', data);
}, this);
// 发送事件
GlobalEvent.send('eventName', 'arg1', 'arg2');
// 发送事件到指定目标
GlobalEvent.sendToTarget('eventName', target, 'arg1', 'arg2');
// 移除事件监听
GlobalEvent.remove('eventName', callback, this);
// 移除指定目标的所有事件监听
GlobalEvent.removeByTarget(this);
// 移除指定事件名和目标的事件监听
GlobalEvent.removeByNameAndTarget('eventName', this);
```

View File

@ -1,94 +0,0 @@
## Http模块
### 特点
- 封装 XMLHttpRequest
- 完整的请求响应接口
- 独立使用简单,一行代码发送一个请求
- 大型项目,管理简单
### 使用
```typescript
import { HttpManager, IHttpEvent, HttpResponseType } from 'kunpocc';
// 1. 使用回调方式处理响应
const event: IHttpEvent = {
name: "login",
onComplete: (response) => {
console.log('请求成功:', response.data);
},
onError: (response) => {
console.log('请求失败:', response.error);
}
};
// POST 请求
HttpManager.post(
"https://api.example.com/login",
{ username: "test", password: "123456" },
"json", // 响应类型:'json' | 'text' | 'arraybuffer'
event,
["Content-Type", "application/json"], // 请求头
5 // 超时时间(秒)
);
// GET 请求
HttpManager.get(
"https://api.example.com/users",
{ id: 1 },
"json",
event
);
// 2. 使用全局事件方式处理响应
GlobalEvent.add(HttpManager.HttpEvent, (result, response) => {
if (result === "succeed") {
console.log('请求成功:', response.data);
} else {
console.log('请求失败:', response.error);
}
}, this);
// 发送请求(不传入 event 参数)
HttpManager.post("https://api.example.com/data", { /* data */ });
```
#### *请求方法*
- `post(url, data, responseType?, event?, headers?, timeout?)`
- `get(url, data, responseType?, event?, headers?, timeout?)`
- `put(url, data, responseType?, event?, headers?, timeout?)`
- `head(url, data, responseType?, event?, headers?, timeout?)`
#### *参数说明*
- `url`: 请求地址
- `data`: 请求数据
- `responseType`: 响应类型(可选,默认 'json'
- `'json'`: JSON 格式
- `'text'`: 文本格式
- `'arraybuffer'`: 二进制数据
- `event`: 请求事件回调(可选)
- `headers`: 请求头(可选)
- `timeout`: 超时时间单位秒可选0表示不超时
#### *响应处理*
1. 回调方式(通过 IHttpEvent
```typescript
const event: IHttpEvent = {
name: "自定义名称",
data?: "自定义数据", // 可选
onComplete: (response) => {
// 成功回调
},
onError: (response) => {
// 失败回调
}
};
```
2. 全局事件方式:
```typescript
GlobalEvent.add(HttpManager.HttpEvent, (result, response) => {
// result: "succeed" | "fail"
// response: IHttpResponse
}, this);
```

View File

@ -1,45 +0,0 @@
## socket网络模块
* 目的抹平小游戏平台和原生平台的使用差异
`各个小游戏平台都是自己封装的socket 和 浏览器标准的websocket在用法上有一定的差异`
#### 使用
```typescript
import { Socket } from "kunpocc";
// 创建一个连接
let url = "wss:xxxxxxxx"
let socket = new Socket(url, { binaryType: "arraybuffer" });
// 监听连接open事件
socket.onopen = () => {
log("连接成功");
}
// 监听收到服务端的消息
socket.onmessage = (data: string | ArrayBuffer) => {
log("收到消息", data);
}
// 监听连接关闭的事件
socket.onclose = (code: number, reason: string) => {
log("连接关闭", code, reason);
socket = null;
}
// 发送字符串消息
socket.send("发送给服务端的消息");
// 发送二进制数据 一般都是使用ProtoBuf具体使用可参考Demo
socket.sendBuffer(buffer);
// 主动断开连接
socket.close(3001, "主动断开连接");
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -1,6 +1,6 @@
{
"name": "kunpocc",
"version": "1.1.4",
"version": "1.1.5",
"description": "基于creator3.0+的kunpocc库",
"main": "./dist/kunpocc.cjs",
"module": "./dist/kunpocc.mjs",
@ -44,7 +44,8 @@
},
"dependencies": {
"fairygui-cc": "^1.2.2",
"kunpocc-event": "^0.0.2"
"kunpocc-event": "^0.0.2",
"kunpocc-net": "^0.0.2"
},
"devDependencies": {
"@cocos/creator-types": "^3.8.0",

View File

@ -5,8 +5,8 @@
*/
import { game, native, sys } from "cc";
import { ReadNetFile } from "kunpocc-net";
import { ICheckUpdatePromiseResult, IPromiseResult } from "../interface/PromiseResult";
import { ReadNetFile } from "../net/nettools/ReadNetFile";
import { debug, warn } from "../tool/log";
import { Time } from "../tool/Time";
import { Utils } from "../tool/Utils";

View File

@ -12,19 +12,6 @@ export { MathTool } from "./tool/Math";
export { md5 } from "./tool/MD5";
export { Time } from "./tool/Time";
/** Http */
export * from "./net/http/HttpManager";
export { HttpTask } from "./net/http/HttpTask";
export { IHttpEvent } from "./net/http/IHttpEvent";
export { IHttpRequest } from "./net/http/IHttpRequest";
export { IHttpResponse } from "./net/http/IHttpResponse";
/** Socket */
export { Socket } from "./net/socket/Socket";
/** 读取网络文件 */
export { ReadNetFile } from "./net/nettools/ReadNetFile";
/** UI */
export { Window } from "./fgui/Window";
export { WindowHeader } from "./fgui/WindowHeader";

View File

@ -1,102 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2024-12-28
* @Description:
*/
import { HttpRequest } from "./HttpRequest";
import { IHttpEvent } from "./IHttpEvent";
import { IHttpResponse } from "./IHttpResponse";
/** http请求方法 */
export type HttpRequestMethod = "GET" | "POST" | "HEAD" | "PUT"
/** http响应类型 */
export type HttpResponseType = "text" | "json" | "arraybuffer";
/** http响应数据类型 */
export type HttpResponseDataType = string | ArrayBuffer | object;
export class HttpManager {
public static HttpEvent: string = "event::http";
/**
* post请求
* @param {string} url
* @param {any} data
* @param {HttpResponseType} responseType
* @param {IHttpEvent} netEvent
* @param {any[]} headers [key1, value1, key2, value2, ...]
* @param {number} timeout (s) 0 (0)
*/
public static post(url: string, data: any, responseType: HttpResponseType = "json", netEvent: IHttpEvent, headers?: any[], timeout: number = 0): HttpRequest {
return this._send("POST", url, data, responseType, netEvent, headers, timeout);
}
/**
* get请求
* @param {string} url
* @param {any} data
* @param {HttpResponseType} responseType
* @param {IHttpEvent} netEvent
* @param {any[]} headers [key1, value1, key2, value2, ...]
* @param {number} timeout (s) 0 (0)
*/
public static get(url: string, data: any, responseType: HttpResponseType = "json", netEvent: IHttpEvent, headers?: any[], timeout: number = 0): HttpRequest {
return this._send("GET", url, data, responseType, netEvent, headers, timeout);
}
/**
* put请求
* @param {string} url
* @param {any} data
* @param {HttpResponseType} responseType
* @param {IHttpEvent} netEvent
* @param {any[]} headers [key1, value1, key2, value2, ...]
* @param {number} timeout (s) 0 (0)
*/
public static put(url: string, data: any, responseType: HttpResponseType = "json", netEvent: IHttpEvent, headers?: any[], timeout: number = 0): HttpRequest {
return this._send("PUT", url, data, responseType, netEvent, headers, timeout);
}
/**
* head请求
* @param {string} url
* @param {any} data
* @param {HttpResponseType} responseType
* @param {IHttpEvent} netEvent
* @param {any[]} headers [key1, value1, key2, value2, ...]
* @param {number} timeout (s) 0 (0)
*/
public static head(url: string, data: any, responseType: HttpResponseType = "json", netEvent: IHttpEvent, headers?: any[], timeout: number = 0): HttpRequest {
return this._send("HEAD", url, data, responseType, netEvent, headers, timeout);
}
/**
* http请求
* @param {HttpRequestMethod} method
* @param {string} url
* @param {any} data
* @param {HttpResponseType} responseType
* @param {IHttpEvent} netEvent
* @param {any[]} headers [key1, value1, key2, value2, ...]
* @param {number} timeout (s) 0 (0)
* @internal
*/
private static _send(method: HttpRequestMethod, url: string, data: any, responseType: HttpResponseType, netEvent: IHttpEvent, headers?: any[], timeout?: number): HttpRequest {
let http = new HttpRequest()
http.setNetCallback((result: "succeed" | "fail", response: IHttpResponse) => {
switch (result) {
case "succeed":
netEvent?.onComplete(response);
break;
case "fail":
netEvent?.onError(response);
break;
}
});
http.method = method;
http.timeout = timeout;
http.responseType = responseType;
http.send(url, data, headers);
return http;
}
}

View File

@ -1,168 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2024-12-28
* @Description:
*/
import { Platform } from "../../global/Platform";
import { HttpRequestMethod, HttpResponseDataType, HttpResponseType } from "./HttpManager";
import { IHttpRequest } from "./IHttpRequest";
import { IHttpResponse } from "./IHttpResponse";
export class HttpRequest implements IHttpRequest, IHttpResponse {
/** 请求方法 */
public method: HttpRequestMethod;
/** xhr实例 @internal */
private _xhr: XMLHttpRequest;
/** 请求超时时间 (s) */
public timeout: number;
/** 响应类型 */
public responseType: HttpResponseType;
/** 信息 */
public message: string;
/** 响应数据 */
public data: HttpResponseDataType;
/** 网络事件回调 @internal */
private _callback: (result: "succeed" | "fail", response: IHttpResponse) => void;
/**
* http相应状态码
* @readonly
* @type {number}
*/
public get statusCode(): number {
return this._xhr.status;
}
/** 相应头 */
public get headers(): any {
return this._xhr.getAllResponseHeaders();
}
constructor() {
this._xhr = new XMLHttpRequest();
}
public setNetCallback(callback: (result: "succeed" | "fail", response: IHttpResponse) => void): void {
this._callback = callback;
}
public send(url: string, data: any, headers: any[]): void {
let xhr = this._xhr;
/** 设置请求超时时间 */
xhr.timeout = this.timeout * 1000;
/** 设置响应类型 */
xhr.responseType = this.responseType;
xhr.onabort = this._onHttpAbort.bind(this);
xhr.onerror = this._onHttpError.bind(this);
xhr.onload = this._onHttpLoad.bind(this);
xhr.ontimeout = this._onHttpTimeout.bind(this);
xhr.open(this.method, encodeURI(url));
if (headers) {
for (let i = 0; i < headers.length; i += 2) {
xhr.setRequestHeader(headers[i], headers[i + 1]);
}
} else if (!Platform.isMobile && Platform.isBrowser) {
if (!data || typeof data == "string") {
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
} else {
xhr.setRequestHeader("Content-Type", "application/json");
}
}
xhr.send(data);
}
/**
* Http请求
* @param {boolean} [silent=false] true则不会回调错误信息
*/
public abort(silent: boolean = false): void {
if (silent) {
this._clear();
}
this._xhr.abort();
}
/**
*
* @internal
*/
private _onHttpAbort(): void {
this.message = "request aborted by user";
this.onError();
}
/**
*
* @internal
*/
private _onHttpError(): void {
this.message = "request error";
this.onError();
}
/**
* @internal
*/
private _onHttpLoad(): void {
const xhr = this._xhr;
const status = xhr.status !== undefined ? xhr.status : 200;
if (status === 200 || status === 204 || status === 0) {
this.onComplete();
} else {
this.message = 'status:' + xhr.status + 'statusText:' + xhr.statusText + "responseURL:" + xhr.responseURL;
this.onError();
}
}
/**
*
* @internal
*/
private _onHttpTimeout(): void {
this.message = "request timeout";
this.onError();
}
/**
*
* @internal
*/
private onError(): void {
this._callback?.("fail", this);
this._clear();
}
/**
*
* @internal
*/
private onComplete(): void {
try {
if (this.responseType == "json") {
this.data = this._xhr.response;
} else if (this.responseType == "arraybuffer") {
this.data = this._xhr.response;
} else if (this.responseType == "text") {
this.data = this._xhr.responseText;
}
this._callback?.("succeed", this);
this._clear();
} catch (e) {
console.warn(`http响应数据解析错误HttpResponseType(${this.responseType})\n url: ${this._xhr.responseURL}\n error: ` + e);
this.onError();
}
}
/**
*
* @internal
*/
private _clear(): void {
this._xhr.onabort = null;
this._xhr.onerror = null;
this._xhr.onload = null;
this._xhr.ontimeout = null;
this._callback = null;
}
}

View File

@ -1,21 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2024-12-28
* @Description:
*/
import { IHttpEvent } from "./IHttpEvent";
import { IHttpResponse } from "./IHttpResponse";
export abstract class HttpTask implements IHttpEvent {
/** 名称 */
public name: string;
/** 自定义参数 */
public data?: any;
/** 请求完成 */
public abstract onComplete(response: IHttpResponse): void;
/** 请求错误 */
public abstract onError(response: IHttpResponse): void;
/** 请求开始 */
public abstract start(): void;
}

View File

@ -1,18 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2024-12-28
* @Description:
*/
import { IHttpResponse } from "./IHttpResponse";
export interface IHttpEvent {
/** 名称 */
name?: string;
/** 自定义参数 */
data?: any;
/** 网络请求成功 */
onComplete(response: IHttpResponse): void;
/** 网络请求失败 */
onError(response: IHttpResponse): void;
}

View File

@ -1,15 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2024-12-28
* @Description:
*/
import { HttpRequestMethod, HttpResponseType } from "./HttpManager";
export interface IHttpRequest {
/** 请求方法 */
readonly method: HttpRequestMethod;
/** 请求超时时间 (s) */
readonly timeout: number;
/** 响应类型 */
readonly responseType: HttpResponseType;
}

View File

@ -1,20 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2024-12-28
* @Description:
*/
import { HttpResponseDataType } from "./HttpManager";
export interface IHttpResponse {
/** 信息 */
readonly message: string;
/** 响应数据 */
readonly data: HttpResponseDataType;
/** http状态码 */
readonly statusCode: number;
/** 相应头 */
readonly headers: any;
}

View File

@ -1,25 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2025-04-18
* @Description:
*/
import { Time } from "../../tool/Time";
import { Utils } from "../../tool/Utils";
import { HttpManager } from "../http/HttpManager";
import { IHttpResponse } from "../http/IHttpResponse";
export class ReadNetFile {
constructor(res: { url: string, timeout: number, responseType: "text" | "json" | "arraybuffer", onComplete: (data: any) => void, onError: (code: number, message: string) => void }) {
// 地址上带时间戳参数 确保每次请求都到服务器上请求最新配置,而不是拿到上次请求的缓存数据
let url = Utils.addUrlParam(res.url, "timeStamp", `${Time.now()}`);
HttpManager.get(url, null, res.responseType, {
onComplete: (response: IHttpResponse) => {
res.onComplete(response.data);
},
onError: (response: IHttpResponse) => {
res.onError(response.statusCode, response.message);
}
}, null, res.timeout || 6);
}
}

View File

@ -1,320 +0,0 @@
/**
* @Author: Gongxh
* @Date: 2025-03-28
* @Description: socket
*/
import { Platform } from "../../global/Platform";
import { debug, warn } from "../../tool/log";
type BinaryType = "blob" | "arraybuffer";
interface SocketOptions {
/**
* web
*
* WebSocket
* protocol
*
*/
protocols?: string[];
/**
* 使 Blob
* 使 ArrayBuffer
* @url https://developer.mozilla.org/docs/Web/API/WebSocket/binaryType
*/
binaryType?: BinaryType;
/** 超时时间 默认3000毫秒 */
timeout?: number;
}
export class Socket {
/**
* socket对象
* @internal
*/
private _socket: WebSocket | WechatMiniprogram.SocketTask | AliyMiniprogram.SocketTask | BytedanceMiniprogram.SocketTask;
/**
* @param {string} url URL WebSocket URL
* @param {SocketOptions} options
*/
constructor(url: string, options?: SocketOptions) {
if (Platform.isWX) {
this._socket = this.createWechatSocket(url, options?.timeout || 3000, options?.protocols);
} else if (Platform.isAlipay) {
this._socket = this.createAliSocket(url, options?.timeout || 3000, options?.protocols);
} else if (Platform.isBytedance) {
this._socket = this.createBytedanceSocket(url, options?.timeout || 3000, options?.protocols);
} else {
this._socket = this.createOtherSocket(url, options?.binaryType, options?.timeout || 3000, options?.protocols);
}
}
/**
* socket
* @internal
*/
private createWechatSocket(url: string, timeout?: number, protocols?: string[]): WechatMiniprogram.SocketTask {
let socket = wx.connectSocket({
url,
protocols: protocols,
timeout: timeout,
success: () => { debug("socket success") },
fail: () => { warn("socket fail") }
});
socket.onOpen(() => {
this.onopen && this.onopen();
});
socket.onMessage((res: { data: string | ArrayBuffer }) => {
this.onmessage && this.onmessage(res.data);
});
socket.onError((res: { errMsg: string }) => {
// 微信上socket和原生平台以及浏览器不一致 所以这里特殊处理 给他一个默认的错误码
this.onclose?.(1000, res?.errMsg);
});
socket.onClose((res: { code: number, reason: string }) => {
this.onclose?.(res.code, res.reason);
});
return socket;
}
/**
* socket
* @internal
*/
private createAliSocket(url: string, timeout?: number, protocols?: string[]): AliyMiniprogram.SocketTask {
let socket = my.connectSocket({
url,
protocols: protocols,
multiple: true,
timeout: timeout,
success: () => { debug("socket success") },
fail: () => { warn("socket fail") }
});
socket.onOpen((info: AliyMiniprogram.OnOpenData) => {
this.onopen && this.onopen();
});
socket.onMessage((info: AliyMiniprogram.OnMessageData) => {
if (!this.onmessage) {
return;
}
if (info.isBuffer) {
if (my.base64ToArrayBuffer) {
this.onmessage(my.base64ToArrayBuffer(info.data.data));
} else if (atob) {
this.onmessage(this.base64ToArrayBuffer(info.data.data));
} else {
this.onmessage(info.data.data);
}
this.onmessage(info.data.data);
} else {
this.onmessage(info.data.data);
}
});
socket.onError((info: { data: AliyMiniprogram.CallBack.Fail }) => {
this.onclose && this.onclose(info.data.error, info.data.errorMessage);
});
socket.onClose((info: { code: number, reason: string, data: { code: number, reason: string } }) => {
this.onclose && this.onclose(info.code, info.reason);
});
return socket;
}
/**
* socket
* @internal
*/
private createBytedanceSocket(url: string, timeout?: number, protocols?: string[]): BytedanceMiniprogram.SocketTask {
let socket: BytedanceMiniprogram.SocketTask = tt.connectSocket({
url,
protocols: protocols,
success: () => { debug("socket success") },
fail: () => { warn("socket fail") }
});
let timer = setTimeout(() => {
socket.close({});
}, timeout);
socket.onOpen(() => {
timer && clearTimeout(timer);
timer = null;
this.onopen && this.onopen();
});
socket.onMessage((info: { data: string | ArrayBuffer }) => {
this.onmessage && this.onmessage(info.data);
});
socket.onError((res: { errMsg: string }) => {
timer && clearTimeout(timer);
timer = null;
// 微信上socket和原生平台以及浏览器不一致 所以这里特殊处理 给他一个默认的错误码
this.onclose?.(1000, res.errMsg);
});
socket.onClose((res: { code: string, reason: string }) => {
timer && clearTimeout(timer);
timer = null;
this.onclose?.(Number(res.code), res.reason);
});
return socket;
}
/**
* socket
* @internal
*/
private createOtherSocket(url: string, binaryType: BinaryType, timeout?: number, protocols?: string[]): WebSocket {
let socket = new WebSocket(url, protocols);
if (binaryType) {
socket.binaryType = binaryType;
}
let timer = setTimeout(() => {
socket.close();
}, timeout);
socket.onopen = () => {
timer && clearTimeout(timer);
timer = null;
this.onopen?.();
}
socket.onmessage = (event: MessageEvent) => {
this.onmessage?.(event.data);
}
socket.onerror = () => {
timer && clearTimeout(timer);
timer = null;
this.onerror?.();
}
socket.onclose = (event: CloseEvent) => {
timer && clearTimeout(timer);
timer = null;
this.onclose?.(event?.code, event?.reason);
}
return socket;
}
/**
*
* @param data -
*/
public send(data: string): void {
if (Platform.isWX) {
(this._socket as WechatMiniprogram.SocketTask).send({ data: data });
} else if (Platform.isAlipay) {
(this._socket as AliyMiniprogram.SocketTask).send({ data: data });
} else if (Platform.isBytedance) {
(this._socket as BytedanceMiniprogram.SocketTask).send({ data: data });
} else {
(this._socket as WebSocket).send(data);
}
}
/**
*
* @param data -
*/
public sendBuffer(data: ArrayBuffer): void {
if (Platform.isWX) {
(this._socket as WechatMiniprogram.SocketTask).send({ data: data });
} else if (Platform.isAlipay) {
if (my.arrayBufferToBase64) {
(this._socket as AliyMiniprogram.SocketTask).send({ data: my.arrayBufferToBase64(data), isBuffer: true });
} else if (btoa) {
(this._socket as AliyMiniprogram.SocketTask).send({ data: this.uint8ArrayToBase64(new Uint8Array(data)), isBuffer: true });
} else {
(this._socket as AliyMiniprogram.SocketTask).send({ data: data });
}
} else if (Platform.isBytedance) {
(this._socket as BytedanceMiniprogram.SocketTask).send({ data: data });
} else {
(this._socket as WebSocket).send(data);
}
}
/**
*
* @param code - 关闭代码: 如果没有传这个参数使1000, 使: [3001-3999]
* @param reason - 关闭原因: 一个人类可读的字符串 UTF-8 123
*/
public close(code?: number, reason?: string): void {
if (Platform.isWX) {
(this._socket as WechatMiniprogram.SocketTask).close({ code: code, reason: reason });
} else if (Platform.isAlipay) {
(this._socket as AliyMiniprogram.SocketTask).close({ code: code, reason: reason });
} else if (Platform.isBytedance) {
(this._socket as BytedanceMiniprogram.SocketTask).close({ code: code, reason: reason });
} else {
(this._socket as WebSocket).close(code, reason);
}
}
/**
* socket示例
* socket实例类型
*/
public socket<T>(): T {
return this._socket as T;
}
/**
* socket已准备好 open成功
*
*/
public onopen: () => void;
/**
*
* @param data -
*/
public onmessage: (data: string | ArrayBuffer) => void;
/**
*
*/
public onerror: () => void;
/**
*
* @param code -
* @param reason -
*/
public onclose: (code: number, reason: string) => void;
/**
* Base64 ()
* @internal
*/
private uint8ArrayToBase64(u8Array: Uint8Array): string {
let CHUNK_SIZE = 0x8000; // 32768
let index = 0;
let length = u8Array.length;
let result = '';
let slice: Uint8Array<ArrayBufferLike>;;
// 分段处理,避免`btoa`输入字符串过长
for (; index < length; index += CHUNK_SIZE) {
slice = u8Array.subarray(index, Math.min(index + CHUNK_SIZE, length));
// 将Uint8Array转换为字符串并使用btoa进行Base64编码
result += btoa(String.fromCharCode(...slice));
}
return result;
}
/**
* base64转成ArrayBuffer ()
* @internal
*/
private base64ToArrayBuffer(base64: string): ArrayBuffer {
let binary_string = atob(base64);
let len = binary_string.length;
let bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
}