149 lines
5.0 KiB
TypeScript
Raw Normal View History

2024-08-26 16:44:51 +08:00
import { CoroutineV2 } from "@/CatanEngine/CoroutineV2/CoroutineV2";
import { Encoding } from "@/CatanEngine/CSharp/System/Text/Encoding";
import { ClientData } from "@/shared/protocols/define/interface";
import { IncomingMessage } from "http";
import { WebSocket } from "ws";
import { Action } from "../../../../CatanEngine/CSharp/System/Action";
import { INetRequest } from "./Core/INetRequest";
import { INetResponse } from "./Core/INetResponse";
let id = 1;
export class NetConnector {
readonly OnDataReceived: Action<INetResponse<any>> = new Action<INetResponse<any>>();
readonly OnDisconnected: Action<void> = new Action<void>();
readonly OnLoadUIMask: Action<boolean> = new Action<boolean>();
public static readonly clients = new Map<WebSocket, ClientData>();
public static OnWebSocketConnection(socket: WebSocket, request: IncomingMessage) {
const ip = request.socket.remoteAddress.replace("::ffff:", "") || 'Unknown IP';
console.log(`Client connected from IP: ${ip}`);
NetConnector.clients.set(socket, { socket, id: id, name: "", money: 0 });
id++;
socket.on('message', (message: Buffer) => NetConnector.OnWebSocketMessage(socket, message));
socket.on('close', NetConnector.OnWebSocketClose);
}
public static async OnWebSocketMessage(socket: WebSocket, message: Buffer) {
// 将 Buffer 转换为 ArrayBuffer
const buffer = message.buffer.slice(message.byteOffset, message.byteOffset + message.byteLength);
let startIndex = 0, byteLength = buffer.byteLength;
while (startIndex + 4 < byteLength) {
const view: DataView = new DataView(buffer, 0, 3);
const strlen: number = view.getUint16(0, true) + (view.getUint8(2) << 16);
const decoder: TextDecoder = new TextDecoder("utf-8");
const str: string = decoder.decode(new Uint8Array(buffer, startIndex + 4, strlen));
startIndex += strlen + 4;
// try {
let json = JSON.parse(str);
let method = <string>json[0];
let data = json[1];
let req = <INetRequest<any>>{
Method: method,
Data: data,
};
if (data) {
console.log(`[RPC] 收到client呼叫: ${req.Method}(${JSON.stringify(req.Data)})`);
} else {
console.log(`[RPC] 收到client呼叫: ${req.Method}()`);
}
// 动态导入处理函数
try {
// 动态导入文件
const module = await import(`@/api/${req.Method.replace(".", "/")}`);
// 调用导入模块中的处理函数
if (module.default) {
let AsyncFunction: () => IterableIterator<any> = function* (): IterableIterator<any> {
const clientData: ClientData = NetConnector.clients.get(socket);
const response: INetResponse<any> = yield* module.default(clientData, req);
if (response) {
NetConnector.Send(socket, response);
}
};
CoroutineV2.Single(AsyncFunction()).Start();
} else {
throw new Error(`Module for ${req.Method} does not export a default function.`);
}
} catch (error) {
console.error(`Error handling request ${req.Method}: ${error.message}`);
const response: INetResponse<any> = {
Status: -1,
Method: req.Method,
Data: null,
IsValid: false
};
NetConnector.Send(socket, response);
}
// const module = await import(`@/api/${req.Method.replace(".", "/")}`);
// if (module) {
// let AsyncFunction: () => IterableIterator<any> = function* (): IterableIterator<any> {
// const response: INetResponse<any> = yield* module.default(req);
// NetConnector.Send(socket, response);
// };
// CoroutineV2.Single(AsyncFunction()).Start();
// } else {
// const response: INetResponse<any> = {
// Status: -1,
// Method: req.Method,
// Data: null,
// IsValid: false
// };
// NetConnector.Send(socket, response);
// }
// } catch (e) {
// console.error(e);
// throw new Error(`[RPC] 無法解析Server回應: ${str}`);
// }
}
}
public static OnWebSocketClose() {
console.log('Client disconnected');
}
private static Send(socket: WebSocket, resp: INetResponse<any>) {
let json: any = [resp.Method, [resp.Status]];
//@ts-ignore
if (resp.Data != null && resp.Data != undefined && resp.Data != NaN) {
json[1].push(resp.Data);
}
//@ts-ignore
if (resp.Data != null && resp.Data != undefined && resp.Data != NaN) {
console.log(`[RPC] 回傳client呼叫:(${resp.Status}): ${resp.Method}(${JSON.stringify(resp.Data)})`);
} else {
console.log(`[RPC] 回傳client呼叫:(${resp.Status}): ${resp.Method}()`);
}
let str = JSON.stringify(json);
if (str.length > 65535) {
throw new Error("要傳的資料太大囉");
}
let strary = Encoding.UTF8.GetBytes(str);
let buffer = new Uint8Array(4 + strary.byteLength);
let u16ary = new Uint16Array(buffer.buffer, 0, 3);
u16ary[0] = strary.byteLength;
buffer[3] = 0x01;
buffer.set(strary, 4);
socket.send(buffer);
}
}
const ErrorResponse: INetResponse<any> = {
Status: -1,
Method: "",
Data: {},
IsValid: false
};