91 行
2.6 KiB
TypeScript
91 行
2.6 KiB
TypeScript
import { _decorator, Component } from 'cc';
|
||
|
||
const { ccclass, property } = _decorator;
|
||
|
||
/**
|
||
* NetworkManager 负责 HTTP REST 与 WebSocket(Nakama Realtime)连接封装。
|
||
*/
|
||
@ccclass('NetworkManager')
|
||
export class NetworkManager extends Component {
|
||
@property
|
||
public baseUrl: string = 'https://api.honghuang.example.com';
|
||
|
||
@property
|
||
public wsUrl: string = 'wss://nakama.honghuang.example.com/ws';
|
||
|
||
private _token: string = '';
|
||
private _socket: WebSocket | null = null;
|
||
|
||
public setToken(token: string): void {
|
||
this._token = token;
|
||
}
|
||
|
||
/**
|
||
* GET 请求
|
||
*/
|
||
public async get(path: string): Promise<any> {
|
||
return this._request('GET', path, null);
|
||
}
|
||
|
||
/**
|
||
* POST 请求
|
||
*/
|
||
public async post(path: string, body: any): Promise<any> {
|
||
return this._request('POST', path, body);
|
||
}
|
||
|
||
/**
|
||
* DELETE 请求
|
||
*/
|
||
public async delete(path: string): Promise<any> {
|
||
return this._request('DELETE', path, null);
|
||
}
|
||
|
||
private async _request(method: string, path: string, body: any): Promise<any> {
|
||
const headers: Record<string, string> = {
|
||
'Content-Type': 'application/json',
|
||
'X-Client-Version': '1.0.0',
|
||
};
|
||
if (this._token) {
|
||
headers['Authorization'] = `Bearer ${this._token}`;
|
||
}
|
||
const resp = await fetch(`${this.baseUrl}${path}`, {
|
||
method,
|
||
headers,
|
||
body: body ? JSON.stringify(body) : undefined,
|
||
});
|
||
return resp.json();
|
||
}
|
||
|
||
/**
|
||
* 连接 Nakama Realtime Socket
|
||
*/
|
||
public connectSocket(): void {
|
||
if (this._socket) {
|
||
return;
|
||
}
|
||
// Nakama 实际连接需要先做 token 握手,此处仅保留接口桩
|
||
this._socket = new WebSocket(`${this.wsUrl}?token=${encodeURIComponent(this._token)}`);
|
||
this._socket.onopen = () => { console.log('Socket opened'); };
|
||
this._socket.onmessage = (ev) => { this._onSocketMessage(ev.data); };
|
||
this._socket.onerror = (ev) => { console.error('Socket error', ev); };
|
||
this._socket.onclose = () => { this._socket = null; };
|
||
}
|
||
|
||
public disconnectSocket(): void {
|
||
this._socket?.close();
|
||
this._socket = null;
|
||
}
|
||
|
||
public sendSocket(data: any): void {
|
||
if (this._socket && this._socket.readyState === WebSocket.OPEN) {
|
||
this._socket.send(JSON.stringify(data));
|
||
}
|
||
}
|
||
|
||
private _onSocketMessage(data: any): void {
|
||
// TODO: 根据 event_type 分发到 EventFeedPanel / EncounterBubble / BattleScene 等
|
||
console.log('Socket message', data);
|
||
}
|
||
}
|