/** * @zh 网络服务模块 * @en Network Service Module */ import { RpcClient, type ProtocolDef, type ApiNames, type MsgNames, type ApiInput, type ApiOutput, type MsgData, type RpcClientOptions, } from '@esengine/rpc/client' import { gameProtocol, type GameProtocol, type PlayerInput } from '../protocol' // ============================================================================ // Types | 类型定义 // ============================================================================ /** * @zh 连接状态 * @en Connection state */ export const enum NetworkState { Disconnected = 0, Connecting = 1, Connected = 2, } /** * @zh 网络服务配置 * @en Network service options */ export interface NetworkServiceOptions extends RpcClientOptions { /** * @zh 服务器地址 * @en Server URL */ url: string } // ============================================================================ // RpcService - Base Class | RPC 服务基类 // ============================================================================ /** * @zh RPC 服务基类 * @en RPC Service base class * * @zh 纯粹的 RPC 客户端封装,不包含任何游戏特定逻辑 * @en Pure RPC client wrapper without any game-specific logic * * @typeParam P - @zh 协议定义类型 @en Protocol definition type */ export class RpcService
{ protected _client: RpcClient
| null = null protected _state: NetworkState = NetworkState.Disconnected constructor(protected readonly _protocol: P) {} /** * @zh 获取连接状态 * @en Get connection state */ get state(): NetworkState { return this._state } /** * @zh 是否已连接 * @en Whether connected */ get isConnected(): boolean { return this._state === NetworkState.Connected } /** * @zh 获取底层 RPC 客户端 * @en Get underlying RPC client */ get client(): RpcClient
| null {
return this._client
}
/**
* @zh 连接到服务器
* @en Connect to server
*/
async connect(options: NetworkServiceOptions): Promise
): Promise ): void {
this._client?.send(name, data)
}
/**
* @zh 监听消息
* @en Listen to message
*/
on ) => void
): this {
this._client?.on(name, handler)
return this
}
/**
* @zh 取消监听消息
* @en Remove message listener
*/
off ) => void
): this {
this._client?.off(name, handler)
return this
}
/**
* @zh 监听消息(只触发一次)
* @en Listen to message (once)
*/
once ) => void
): this {
this._client?.once(name, handler)
return this
}
}
// ============================================================================
// GameNetworkService - Game-specific Class | 游戏网络服务
// ============================================================================
/**
* @zh 游戏网络服务
* @en Game network service
*
* @zh 基于默认游戏协议的网络服务,提供游戏特定的便捷方法
* @en Network service based on default game protocol with game-specific convenience methods
*
* @example
* ```typescript
* const network = new GameNetworkService()
* await network.connect({ url: 'ws://localhost:3000' })
*
* // 游戏特定的便捷方法
* network.sendInput({ frame: 1, moveDir: { x: 1, y: 0 } })
*
* network.onSync((data) => {
* for (const entity of data.entities) {
* // 更新实体状态
* }
* })
* ```
*/
export class GameNetworkService extends RpcService (protocol: P): RpcService
export function createNetworkService (protocol?: P): RpcService | GameNetworkService {
if (protocol) {
return new RpcService(protocol)
}
return new GameNetworkService()
}