-
Notifications
You must be signed in to change notification settings - Fork 107
Description
First of all, this is an awesome library and I'm heavily experimenting with very interesting use cases.
One thing that I still struggle with after lots of experimentation is bidirectional calling and I'd like to clarify if what I'm aiming for is even intended to work. Simply put, I'd like to register a callback from a client in a Durable Object, which then executes the callback(s) upon certain events happening.
Here are some relevant sections of the code:
Server (Durable Object)
import { DurableObject, RpcStub } from "cloudflare:workers";
export class MyRpcServer extends DurableObject {
#subscriptions: Set<RpcStub<(message: string) => void>> = new Set();
async addMessage(message: string) {
console.log("DO: Adding message:", message);
console.log("DO: Number of subscribers:", this.#subscriptions.size);
for (const sub of this.#subscriptions) {
console.log("DO: Sending message to subscriber");
await sub(message);
console.log("DO: Should be sent");
}
}
subscribe(callback: RpcStub<(message: string) => void>) {
console.log("DO: Subscribing");
this.#subscriptions.add(callback);
return () => {
console.log("DO: Unsubscribing");
this.#subscriptions.delete(callback);
};
}
}Client
const localReceiveMessage = (message: string) => {
console.log("Adding message", message);
};
let api = newWebSocketRpcSession<MyRpcServer>("ws://localhost:5173/rpc");
api.subscribe(new RpcStub<(message: string) => void>(localReceiveMessage))If I execute the callback immediately within the subscribe function, it works. But if I store it and then execute it later (upon receiving a message via addMessage within the DO), it fails with Error: RPC stub used after being disposed.. I have read the README section about automatic disposal and also tried lots of variations of the code, duplicating the stubs with dup(), but to no avail so far.
I've created a reproducible example here: https://github.com/bndkt/rpc-example and would appreciate any pointes on whether this should be a supported scenario at all and if yes, where I'm missing something.