RPC Library
@esengine/rpc is a lightweight, type-safe RPC (Remote Procedure Call) library designed for games and real-time applications.
Features
Section titled “Features”- Type-Safe: Complete TypeScript type inference for API calls and message handling
- Bidirectional: Supports both request-response (API) and publish-subscribe (message) patterns
- Flexible Codecs: Built-in JSON and MessagePack codecs
- Cross-Platform: Works in browsers, Node.js, and WeChat Mini Games
Installation
Section titled “Installation”npminstall@esengine/rpcQuick Start
Section titled “Quick Start”1. Define Protocol
Section titled “1. Define Protocol”import { rpc } from'@esengine/rpc';// Define protocol (shared between client and server)export const chatProtocol = rpc.define({api: {// Request-response APIslogin: rpc.api<{ username:string }, { userId:string; token:string }>(),sendMessage: rpc.api<{ text:string }, { messageId:string }>(),},msg: {// One-way messages (publish-subscribe)newMessage: rpc.msg<{ from:string; text:string; time:number }>(),userJoined: rpc.msg<{ username:string }>(),userLeft: rpc.msg<{ username:string }>(),},});exporttype ChatProtocol =typeof chatProtocol;2. Create Client
Section titled “2. Create Client”import { RpcClient } from'@esengine/rpc/client';import { chatProtocol } from'./protocol';// Create clientconst client = newRpcClient(chatProtocol, 'ws://localhost:3000', {onConnect: () =>console.log('Connected'),onDisconnect: (reason) =>console.log('Disconnected:', reason),onError: (error) =>console.error('Error:', error),});// Connect to serverawait client.connect();// Call API (type-safe)const { userId, token } = await client.call('login', { username: 'player1' });console.log('Logged in:', userId);// Listen to messages (type-safe)client.on('newMessage', (data)=> {console.log(`${data.from}: ${data.text}`);});// Send messageawait client.call('sendMessage', { text: 'Hello!' });3. Create Server
Section titled “3. Create Server”import { serve } from'@esengine/rpc/server';import { chatProtocol } from'./protocol';// Create server (API handlers defined in config)const server = serve(chatProtocol, {port: 3000,onStart: (port) =>console.log(`Server started: ws://localhost:${port}`),api: {login: async (input, conn) => {const userId = generateUserId();const token = generateToken();// Broadcast user joinedserver.broadcast('userJoined', { username: input.username });return { userId, token };},sendMessage: async (input, conn) => {const messageId = generateMessageId();// Broadcast new messageserver.broadcast('newMessage', {from: conn.id,text: input.text,time: Date.now(),});return { messageId };},},});// Start serverawait server.start();Core Concepts
Section titled “Core Concepts”Protocol Definition
Section titled “Protocol Definition”A protocol is the contract between client and server:
const protocol = rpc.define({api: {// API: Request-response pattern, client initiates, server handles and returnsmethodName: rpc.api<InputType, OutputType>(),},msg: {// Message: Publish-subscribe pattern, either side can send, other side listensmessageName: rpc.msg<DataType>(),},});API vs Messages
Section titled “API vs Messages”| Feature | API | Message |
|---|---|---|
| Pattern | Request-Response | Publish-Subscribe |
| Return Value | Yes (Promise) | No |
| Confirmation | Waits for response | Fire-and-forget |
| Use Cases | Login, queries, operations | Real-time notifications, state sync |
Codecs
Section titled “Codecs”Two built-in codecs are available:
import { json, msgpack } from'@esengine/rpc/codec';// JSON (default, human-readable)const client = newRpcClient(protocol, url, {codec: json(),});// MessagePack (binary, more efficient)const client = newRpcClient(protocol, url, {codec: msgpack(),});Documentation
Section titled “Documentation”- Client API - Detailed RpcClient API
- Server API - Detailed RpcServer API
- Codecs - Custom codecs