[add] slot1
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
|
||||
import { Action } from "../../../../../CatanEngine/CSharp/System/Action";
|
||||
import { INetResponse } from "./INetResponse";
|
||||
|
||||
export interface INetConnector {
|
||||
readonly OnDataReceived: Action<INetResponse<any>>;
|
||||
readonly OnDisconnected: Action<void>;
|
||||
readonly IsConnected: boolean;
|
||||
|
||||
// SendAsync<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>): Iterator<any>;
|
||||
// Send<TRequest, TResponse>(req: INetRequest<TRequest, TResponse>);
|
||||
// Logout();
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "f97991b5-0da6-4220-ab29-13c8f8f7e405",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export interface INetRequest<TResponse> {
|
||||
readonly Method: string;
|
||||
readonly Data: TResponse;
|
||||
}
|
||||
|
||||
// import { INetResponse } from "./INetResponse";
|
||||
|
||||
// export interface INetRequest<TRequest, TResponse> {
|
||||
// readonly Method: string;
|
||||
// readonly MethodBack: string;
|
||||
|
||||
// Data: TRequest;
|
||||
// Result: INetResponse<TResponse>;
|
||||
|
||||
// SendAsync(): Iterator<any>;
|
||||
// Send();
|
||||
// }
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "339fcf27-bdb9-4b8f-ae18-dd54c9500145",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface INetResponse<TResponse> {
|
||||
readonly Method: string;
|
||||
readonly Status: number;
|
||||
readonly Data: TResponse;
|
||||
readonly IsValid: boolean;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"ver": "1.1.0",
|
||||
"uuid": "c4cb0cd4-b98c-4f8e-b1e6-ac3b51281b28",
|
||||
"importer": "typescript",
|
||||
"isPlugin": false,
|
||||
"loadPluginInWeb": true,
|
||||
"loadPluginInNative": true,
|
||||
"loadPluginInEditor": false,
|
||||
"subMetas": {}
|
||||
}
|
||||
4
src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts
Normal file
4
src/script/Engine/CatanEngine/NetManagerV2/NetConfig.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export default class NetConfig {
|
||||
/**是否顯示RPC接送JSON的LOG */
|
||||
public static ShowServerLog: boolean = true;
|
||||
}
|
||||
149
src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts
Normal file
149
src/script/Engine/CatanEngine/NetManagerV2/NetConnector.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
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
|
||||
};
|
||||
53
src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts
Normal file
53
src/script/Engine/CatanEngine/NetManagerV2/NetManager.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
// import { INetRequest } from "./Core/INetRequest";
|
||||
// import { NetConnector } from "./NetConnector";
|
||||
|
||||
// export class NetManager {
|
||||
// static get IsConnected() { return this._connector && this._connector.IsConnected; }
|
||||
// static get HasInit() { return this._connector != null; }
|
||||
|
||||
// private static _connector: NetConnector;
|
||||
|
||||
// static Initialize(connector: NetConnector) {
|
||||
// this._connector = connector;
|
||||
// }
|
||||
|
||||
// static ConnectAsync() {
|
||||
// this.CheckConnector();
|
||||
// return this._connector.ConnectAsync();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 斷線
|
||||
// */
|
||||
// static Disconnect() {
|
||||
// this.CheckConnector();
|
||||
// this._connector.Disconnect();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 傳送資料給Server, 不等待回應
|
||||
// * @param req
|
||||
// */
|
||||
// static Send(req: INetRequest<any, any>) {
|
||||
// this.CheckConnector();
|
||||
// if (NativeClass.IsLineProject) {
|
||||
// NativeClass.Instance.GetSend(req);
|
||||
// } else {
|
||||
// this._connector.Send(req);
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * 傳送資料給Server, 並等待回應
|
||||
// * @param req
|
||||
// */
|
||||
// static SendAsync(req: INetRequest<any, any>, mask: boolean) {
|
||||
// this.CheckConnector();
|
||||
// return this._connector.SendAsync(req, mask);
|
||||
// }
|
||||
|
||||
// private static CheckConnector() {
|
||||
// if (!this._connector) throw new Error("請先呼叫CasinoNetManager.Initialize()初始化connector");
|
||||
// }
|
||||
|
||||
// }
|
||||
21
src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts
Normal file
21
src/script/Engine/CatanEngine/NetManagerV2/NetRequest.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
// import { INetRequest } from "./Core/INetRequest";
|
||||
// import { NetManager } from "./NetManager";
|
||||
|
||||
// export abstract class NetRequest<TResquest, TResponse> implements INetRequest<TResquest, TResponse> {
|
||||
// abstract get Method(): string;
|
||||
|
||||
// get MethodBack(): string {
|
||||
// return this.Method;
|
||||
// }
|
||||
|
||||
// Data: TResquest;
|
||||
// Result: import("./Core/INetResponse").INetResponse<TResponse>;
|
||||
|
||||
// SendAsync(mask: boolean = false): Iterator<any> {
|
||||
// return NetManager.SendAsync(this, mask);
|
||||
// }
|
||||
|
||||
// Send() {
|
||||
// NetManager.Send(this);
|
||||
// }
|
||||
// }
|
||||
Reference in New Issue
Block a user