RPC Codecs
Codecs handle serialization and deserialization of RPC messages. Two built-in codecs are available.
Built-in Codecs
Section titled “Built-in Codecs”JSON Codec (Default)
Section titled “JSON Codec (Default)”Human-readable, widely compatible:
import { json } from '@esengine/rpc/codec';
const client = new RpcClient(protocol, url, { codec: json(),});Pros:
- Human-readable (easy debugging)
- No additional dependencies
- Universal browser support
Cons:
- Larger message size
- Slower serialization
MessagePack Codec
Section titled “MessagePack Codec”Binary format, more efficient:
import { msgpack } from '@esengine/rpc/codec';
const client = new RpcClient(protocol, url, { codec: msgpack(),});Pros:
- Smaller message size (~30-50% smaller)
- Faster serialization
- Supports binary data natively
Cons:
- Not human-readable
- Requires msgpack library
Codec Interface
Section titled “Codec Interface”interface Codec { /** * Encode packet to wire format */ encode(packet: unknown): string | Uint8Array;
/** * Decode wire format to packet */ decode(data: string | Uint8Array): unknown;}Custom Codec
Section titled “Custom Codec”Create your own codec for special needs:
import type { Codec } from '@esengine/rpc/codec';
// Example: Compressed JSON codecconst compressedJson: () => Codec = () => ({ encode(packet: unknown): Uint8Array { const json = JSON.stringify(packet); return compress(new TextEncoder().encode(json)); },
decode(data: string | Uint8Array): unknown { const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data; const decompressed = decompress(bytes); return JSON.parse(new TextDecoder().decode(decompressed)); },});
// Use custom codecconst client = new RpcClient(protocol, url, { codec: compressedJson(),});Protocol Buffers Codec
Section titled “Protocol Buffers Codec”For production games, consider Protocol Buffers:
import type { Codec } from '@esengine/rpc/codec';
const protobuf = (schema: ProtobufSchema): Codec => ({ encode(packet: unknown): Uint8Array { return schema.Packet.encode(packet).finish(); },
decode(data: string | Uint8Array): unknown { const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : data; return schema.Packet.decode(bytes); },});Matching Client and Server
Section titled “Matching Client and Server”Both client and server must use the same codec:
import { msgpack } from '@esengine/rpc/codec';export const gameCodec = msgpack();
// client.tsimport { gameCodec } from './shared/codec';const client = new RpcClient(protocol, url, { codec: gameCodec });
// server.tsimport { gameCodec } from './shared/codec';const server = serve(protocol, { port: 3000, codec: gameCodec, api: { /* ... */ },});Performance Comparison
Section titled “Performance Comparison”| Codec | Encode Speed | Decode Speed | Size |
|---|---|---|---|
| JSON | Medium | Medium | Large |
| MessagePack | Fast | Fast | Small |
| Protobuf | Fastest | Fastest | Smallest |
For most games, MessagePack provides a good balance. Use Protobuf for high-performance requirements.
Text Encoding Utilities
Section titled “Text Encoding Utilities”For custom codecs, utilities are provided:
import { textEncode, textDecode } from '@esengine/rpc/codec';
// Works on all platforms (browser, Node.js, WeChat)const bytes = textEncode('Hello'); // Uint8Arrayconst text = textDecode(bytes); // 'Hello'