Designing a Unified Browser Message Communication Library (rpc-shooter) with TypeScript Interfaces and JSON-RPC
This article explains how to build a versatile browser message‑communication library that works across iframes, Web Workers, ServiceWorkers, BroadcastChannel and other MessagePort‑like objects, using a unified interface design, TypeScript typings, event‑driven architecture and JSON‑RPC for reliable remote procedure calls.
The article introduces postMessage as a common mechanism for communication between embedded contexts such as iframe and Web Workers , and explains the need for a higher‑level utility library called rpc-shooter that abstracts the various browser messaging APIs (Window, Worker, SharedWorker, ServiceWorker, MessageChannel, BroadcastChannel, MessagePort).
It starts with a simple parent‑child iframe example, showing raw postMessage usage, then proposes a unified message format and handler map to simplify complex scenarios.
Next, the article treats message communication as an event system, borrowing ideas from socket.io . It defines TypeScript interfaces for RPC handlers and events, and presents a class RPCMessageEvent that encapsulates the sending and receiving endpoints, automatically wiring addEventListener and postMessage calls.
interface RPCHandler { (...args: any[]): any; }
interface RPCEvent { emit(event: string, ...args: any[]): void; on(event: string, fn: RPCHandler): void; off(event: string, fn?: RPCHandler): void; }
// ... (full class implementation omitted for brevity)The design emphasizes interface‑first development, allowing the same abstraction to work with any object that implements a message event and a postMessage method, such as MessagePort or BroadcastChannel .
To make remote calls more ergonomic, the article introduces a promisify layer that maps a request event (prefixed with syn: ) to a response event (prefixed with ack: ) and returns a Promise . It also discusses error handling, timeouts, and data‑serialization issues.
Finally, the article adopts the JSON‑RPC 2.0 specification, defining request and response structures ( RPCSYNEvent , RPCSACKEvent ) and showing how to wrap the event system into a full‑featured RPC client/server that can be used with rpc-shooter or swapped for other transports like socket.io . Example usage in both the main page and a child worker is provided.
The article concludes with a brief mention of the comlink library for worker communication and encourages readers to try the rpc-shooter tool.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.