message-port-rpc v1.0.1
message-port-rpc
Turns a MessagePort
into an remote procedure call (RPC) stub.
Background
Modern web apps often need to deal with multiple JavaScript workers or VMs. The communication channel is often MessagePort
.
By converting a MessagePort
into an RPC stub, we can easily offload a Promise function to a different thread.
How to use
On main thread
Creates a new pair of MessagePort
, pass one of the port to the worker thread, then create a RPC stub on another port.
import { messagePortRPC } from 'message-port-rpc';
// TypeScript: define the function type.
type Fn = (x: number, y: number) => Promise<number>;
// Loads a Web Worker.
const worker = new Worker('./static/worker/js/main.js');
// Creates a new pair of `MessagePort` dedicated for RPC.
const { port1, port2 } = new MessageChannel();
// Sends the dedicated port to the worker.
worker.postMessage(undefined, [port2]);
// Creates a function stub.
const callFunction = messagePortRPC<Fn>(port1);
// Calls the function stub.
const result: number = await callFunction(1, 2);
On worker thread
Receives the MessagePort
and registers an RPC function on the port.
import { messagePortRPC } from 'message-port-rpc';
// TypeScript: define the function type.
type Fn = (x: number, y: number) => Promise<number>;
// Receives the port dedicated for RPC.
addEventListener('message', ({ ports }) => {
// Registers an RPC function on the received `MessagePort`.
messagePortRPC<Fn>(ports[0], (x, y) => Promise.resolve(x + y));
});
API
function messagePortRPC<T extends (...args: any[]) => Promise<unknown>>(
port: MessagePort,
fn?: T
): {
(...args: Parameters<T>): ReturnType<T>;
withOptions: (
args: Parameters<T>,
init: {
signal?: AbortSignal;
tranfer?: Transferable[];
}
) => ReturnType<T>;
};
Behaviors
Why use a dedicated MessagePort
?
Instead of multiplexing multiple messages into a single MessagePort
, a dedicated MessagePort
simplifies the code, and easier to secure the channel.
Internally, for every call, we create a new pair of MessagePort
. The result of the call is passed through the MessagePort
. When the call is resolved/rejected/aborted, the MessagePort
will be shutdown.
Contributions
Like us? Star us.
Want to make it better? File us an issue.
Don't like something you see? Submit a pull request.
4 days ago
2 months ago
5 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
9 months ago
9 months ago
9 months ago
8 months ago
9 months ago
8 months ago
9 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
1 year ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
10 months ago
1 year ago
10 months ago
1 year ago
1 year ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago