mirror of
https://github.com/Gongxh0901/kunpolibrary
synced 2025-07-02 06:14:19 +00:00
拆分网络模块
This commit is contained in:
parent
6953f738b0
commit
5b5e4b5936
@ -42,3 +42,7 @@
|
|||||||
## 1.1.4 事件模块拆分
|
## 1.1.4 事件模块拆分
|
||||||
- 拆分事件模块,使用 `npm install kunpocc-event` 安装
|
- 拆分事件模块,使用 `npm install kunpocc-event` 安装
|
||||||
* 仓库地址: https://github.com/Gongxh0901/kunpocc-event
|
* 仓库地址: https://github.com/Gongxh0901/kunpocc-event
|
||||||
|
|
||||||
|
## 1.1.5 网络模块拆分
|
||||||
|
- 拆分网络模块,使用 `npm install kunpocc-net` 安装
|
||||||
|
* 仓库地址: https://github.com/Gongxh0901/kunpocc-net
|
32
README.md
32
README.md
@ -37,25 +37,23 @@ npm set registry https://npm.aliyun.com
|
|||||||
|
|
||||||
# 目录
|
# 目录
|
||||||
1. [使用教程 (新手必看)](./docs/Noviciate.md)
|
1. [使用教程 (新手必看)](./docs/Noviciate.md)
|
||||||
|
|
||||||
2. [项目配置](./docs/Basic.md)
|
2. [项目配置](./docs/Basic.md)
|
||||||
3. [UI模块](./docs/UI.md)
|
3. [UI模块](./docs/UI.md)
|
||||||
4. [ec模块](https://github.com/Gongxh0901/kunpo-ec)
|
5. [全局计时器](./docs/Timer.md)
|
||||||
5. [ecs模块](https://github.com/Gongxh0901/kunpo-esc)
|
6. [平台工具](./docs/Platform.md)
|
||||||
6. [网络模块](./docs/HTTP.md)
|
7. [屏幕尺寸](./docs/Screen.md)
|
||||||
7. [四叉树](https://github.com/Gongxh0901/kunpo-quadtree)
|
8. [小工具](./docs/Tools.md)
|
||||||
8. [行为树](https://github.com/Gongxh0901/kunpocc-behaviortree)
|
9. [时间](./docs/Time.md)
|
||||||
9. [资源管理](https://github.com/Gongxh0901/kunpocc-assets)
|
10. [小游戏接口封装](./docs/MiniGame.md)
|
||||||
10. [条件显示节点 (一般用于UI上的红点)](./docs/Condition.md)
|
11. [热更新](./docs/HotUpdate.md)
|
||||||
11. [全局事件](./docs/Event.md)
|
12. [条件显示节点 (一般用于UI上的红点)](./docs/Condition.md)
|
||||||
12. [全局计时器](./docs/Timer.md)
|
13. [ec模块](https://github.com/Gongxh0901/kunpo-ec)
|
||||||
13. [平台工具](./docs/Platform.md)
|
14. [ecs模块](https://github.com/Gongxh0901/kunpo-esc)
|
||||||
14. [屏幕尺寸](./docs/Screen.md)
|
15. [网络模块 http和socket](https://github.com/Gongxh0901/kunpocc-net)
|
||||||
15. [小工具](./docs/Tools.md)
|
16. [四叉树](https://github.com/Gongxh0901/kunpo-quadtree)
|
||||||
16. [时间](./docs/Time.md)
|
17. [行为树](https://github.com/Gongxh0901/kunpocc-behaviortree)
|
||||||
17. [socket网络模块](./docs/Socket.md)
|
18. [资源管理](https://github.com/Gongxh0901/kunpocc-assets)
|
||||||
18. [小游戏接口封装](./docs/MiniGame.md)
|
19. [全局事件](https://github.com/Gongxh0901/kunpocc-event)
|
||||||
19. [热更新](./docs/HotUpdate.md)
|
|
||||||
## 类型支持
|
## 类型支持
|
||||||
|
|
||||||
该库完全使用 TypeScript 编写,提供完整的类型定义文件。
|
该库完全使用 TypeScript 编写,提供完整的类型定义文件。
|
||||||
|
@ -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);
|
|
||||||
```
|
|
94
docs/HTTP.md
94
docs/HTTP.md
@ -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);
|
|
||||||
```
|
|
@ -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 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "kunpocc",
|
"name": "kunpocc",
|
||||||
"version": "1.1.4",
|
"version": "1.1.5",
|
||||||
"description": "基于creator3.0+的kunpocc库",
|
"description": "基于creator3.0+的kunpocc库",
|
||||||
"main": "./dist/kunpocc.cjs",
|
"main": "./dist/kunpocc.cjs",
|
||||||
"module": "./dist/kunpocc.mjs",
|
"module": "./dist/kunpocc.mjs",
|
||||||
@ -44,7 +44,8 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fairygui-cc": "^1.2.2",
|
"fairygui-cc": "^1.2.2",
|
||||||
"kunpocc-event": "^0.0.2"
|
"kunpocc-event": "^0.0.2",
|
||||||
|
"kunpocc-net": "^0.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cocos/creator-types": "^3.8.0",
|
"@cocos/creator-types": "^3.8.0",
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { game, native, sys } from "cc";
|
import { game, native, sys } from "cc";
|
||||||
|
import { ReadNetFile } from "kunpocc-net";
|
||||||
import { ICheckUpdatePromiseResult, IPromiseResult } from "../interface/PromiseResult";
|
import { ICheckUpdatePromiseResult, IPromiseResult } from "../interface/PromiseResult";
|
||||||
import { ReadNetFile } from "../net/nettools/ReadNetFile";
|
|
||||||
import { debug, warn } from "../tool/log";
|
import { debug, warn } from "../tool/log";
|
||||||
import { Time } from "../tool/Time";
|
import { Time } from "../tool/Time";
|
||||||
import { Utils } from "../tool/Utils";
|
import { Utils } from "../tool/Utils";
|
||||||
|
@ -12,19 +12,6 @@ export { MathTool } from "./tool/Math";
|
|||||||
export { md5 } from "./tool/MD5";
|
export { md5 } from "./tool/MD5";
|
||||||
export { Time } from "./tool/Time";
|
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 */
|
/** UI */
|
||||||
export { Window } from "./fgui/Window";
|
export { Window } from "./fgui/Window";
|
||||||
export { WindowHeader } from "./fgui/WindowHeader";
|
export { WindowHeader } from "./fgui/WindowHeader";
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user