Files
rougelike-demo/client/assets/scripts/Framework/Net/PlatformAdapter.ts

210 lines
6.4 KiB
TypeScript
Raw Normal View History

2025-12-14 22:39:43 +08:00
import { sys } from 'cc';
// 使用别名导入避免命名冲突
import { BaseServiceType, HttpClient as HttpClientBrowser, WsClient as WsClientBrowser } from 'tsrpc-browser';
import { HttpClient as HttpClientMiniapp, WsClient as WsClientMiniapp } from 'tsrpc-miniapp';
import { NetProtocolType } from './NetConfig';
import { INetClient, WebSocketClientWrapper } from './WebSocketClient';
2025-12-14 22:39:43 +08:00
/**
*
*/
export enum PlatformType {
/** 浏览器平台 */
Browser = "browser",
2025-12-14 22:39:43 +08:00
/** 小程序平台 (微信、抖音、QQ等) */
MiniApp = "miniapp",
2025-12-14 22:39:43 +08:00
/** 未知平台 */
Unknown = "unknown"
}
/**
*
*/
export interface ClientConfig {
/** 服务器地址 */
server: string;
/** 网络协议类型 */
protocolType?: NetProtocolType;
2025-12-14 22:39:43 +08:00
/** 是否使用 JSON 格式 (默认 true) */
json?: boolean;
2025-12-14 22:39:43 +08:00
/** 超时时间(ms) */
timeout?: number;
2025-12-14 22:39:43 +08:00
/** 其他配置 */
[key: string]: any;
}
/**
*
* TSRPC
2025-12-14 22:39:43 +08:00
*
* :
* - HTTP/HTTPS: 用于无状态的API调用
* - WebSocket: 用于实时双向通信
*
* :
2025-12-14 22:39:43 +08:00
* - tsrpc-browser: 用于浏览器和 XMLHttpRequest
* - tsrpc-miniapp: 用于微信QQ
*/
export class PlatformAdapter {
private static _currentPlatform: PlatformType | null = null;
private static _serviceProto: any = null;
/**
*
* @param serviceProto shared
*/
static setServiceProto(serviceProto: any): void {
this._serviceProto = serviceProto;
console.log('[PlatformAdapter] Service protocol set');
}
/**
*
*/
static detectPlatform(): PlatformType {
if (this._currentPlatform) {
return this._currentPlatform;
}
// 检测 QQ 小游戏/小程序
if (sys.platform === sys.Platform.WECHAT_GAME && (window as any).qq) {
this._currentPlatform = PlatformType.MiniApp;
return this._currentPlatform;
}
// 检测微信小游戏/小程序
if (sys.platform === sys.Platform.WECHAT_GAME) {
this._currentPlatform = PlatformType.MiniApp;
return this._currentPlatform;
}
// 检测字节跳动小游戏/小程序
if (sys.platform === sys.Platform.BYTEDANCE_MINI_GAME) {
this._currentPlatform = PlatformType.MiniApp;
return this._currentPlatform;
}
// 检测浏览器
if (sys.isBrowser) {
this._currentPlatform = PlatformType.Browser;
return this._currentPlatform;
}
// 其他原生环境默认使用 Browser 客户端 (XMLHttpRequest 兼容)
console.warn('[PlatformAdapter] Unknown platform, fallback to Browser client');
this._currentPlatform = PlatformType.Browser;
return this._currentPlatform;
}
/**
* TSRPC
2025-12-14 22:39:43 +08:00
* @param config
*/
static createClient<T extends BaseServiceType>(config: ClientConfig): INetClient<T> {
2025-12-14 22:39:43 +08:00
const platform = this.detectPlatform();
const protocolType = config.protocolType || NetProtocolType.Http;
2025-12-14 22:39:43 +08:00
// 默认配置
const defaultConfig: ClientConfig = {
server: config.server,
json: true,
timeout: config.timeout || 30000,
...config
};
// 如果设置了协议,添加到配置中
if (this._serviceProto) {
(defaultConfig as any).proto = this._serviceProto;
} else {
console.warn('[PlatformAdapter] Service protocol not set, please call setServiceProto() first');
}
console.log(`[PlatformAdapter] Creating ${protocolType} client for ${platform}:`, defaultConfig.server);
// 根据协议类型和平台创建对应的客户端
if (protocolType === NetProtocolType.WebSocket) {
return this.createWebSocketClient<T>(platform, defaultConfig);
} else {
return this.createHttpClient<T>(platform, defaultConfig);
}
}
/**
* HTTP
*/
private static createHttpClient<T extends BaseServiceType>(platform: PlatformType, config: ClientConfig): INetClient<T> {
2025-12-14 22:39:43 +08:00
let client: HttpClientBrowser<T> | HttpClientMiniapp<T>;
if (platform === PlatformType.MiniApp) {
client = new HttpClientMiniapp(this._serviceProto, config) as HttpClientMiniapp<T>;
} else {
client = new HttpClientBrowser(this._serviceProto, config) as HttpClientBrowser<T>;
}
// 包装 HTTP 客户端使其符合 INetClient 接口
return {
callApi: async <Req, Res>(apiName: string, req: Req) => {
return await client.callApi(apiName, req);
}
} as INetClient<T>;
}
/**
* WebSocket
*/
private static createWebSocketClient<T extends BaseServiceType>(platform: PlatformType, config: ClientConfig): INetClient<T> {
let wsClient: WsClientBrowser<T> | WsClientMiniapp<T>;
if (platform === PlatformType.MiniApp) {
wsClient = new WsClientMiniapp(this._serviceProto, config) as WsClientMiniapp<T>;
2025-12-14 22:39:43 +08:00
} else {
wsClient = new WsClientBrowser(this._serviceProto, config) as WsClientBrowser<T>;
2025-12-14 22:39:43 +08:00
}
// 使用包装器统一接口
return new WebSocketClientWrapper<T>(wsClient);
2025-12-14 22:39:43 +08:00
}
/**
*
*/
static isMiniApp(): boolean {
return this.detectPlatform() === PlatformType.MiniApp;
}
/**
*
*/
static isBrowser(): boolean {
return this.detectPlatform() === PlatformType.Browser;
}
/**
*
*/
static getCurrentPlatform(): PlatformType {
if (!this._currentPlatform) {
return this.detectPlatform();
}
return this._currentPlatform;
}
/**
*
*/
static getPlatformInfo(): string {
const platform = this.getCurrentPlatform();
const platformName = sys.platform;
const isMobile = sys.isMobile;
const isNative = sys.isNative;
return `Platform: ${platform}, OS: ${platformName}, Mobile: ${isMobile}, Native: ${isNative}`;
}
}