LearnNewsExamplesServices
Frontmatter
id8497
titleServiceWorker: Implement Remote Method Broadcast and Replay for Multi-Client Support
stateClosed
labels
bugaicore
assigneestobiu
createdAtJan 10, 2026, 12:28 PM
updatedAtJan 10, 2026, 12:36 PM
githubUrlhttps://github.com/neomjs/neo/issues/8497
authortobiu
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJan 10, 2026, 12:36 PM

ServiceWorker: Implement Remote Method Broadcast and Replay for Multi-Client Support

Closed v11.20.0 bugaicore
tobiu
tobiu commented on Jan 10, 2026, 12:28 PM

The Service Worker does not properly propagate remote method registration to multiple connected clients (App Workers) or handle new connections after initialization.

The Problem:

  1. Multi-Client Support: Neo.core.Base.promiseRemotes targets 'app', but in a Service Worker context, 'app' represents any connected client. The current logic attempts to send to a single port, missing others.
  2. Future Clients: initRemote runs once on startup. Clients connecting after startup (e.g., opening a new tab) never receive the registerRemote message and cannot access Service Worker methods.
  3. Initialization Crash: promiseRemotes fails if called when no clients are connected (because sendMessage returns null), rejecting the initialization promise.

Proposed Solution: Adopt the "Registry & Replay" pattern used for SharedWorkers (#8339).

  1. src/core/Base.mjs (initRemote):

    • Detect Neo.workerId === 'service'.
    • Store remote.app definitions in Neo.currentWorker.remotesToRegister.
  2. src/worker/ServiceBase.mjs:

    • Add remotesToRegister = [].
    • Update createMessageChannel (triggered by onConnect) to iterate remotesToRegister and send registerRemote to the new client's port.
    • Refine hasWorker('app') to return true only if active ports exist, preventing promiseRemotes from failing when no clients are connected.

This ensures every client—existing or new—receives the remote method definitions.

tobiu added the bug label on Jan 10, 2026, 12:28 PM
tobiu added the ai label on Jan 10, 2026, 12:28 PM
tobiu added the core label on Jan 10, 2026, 12:28 PM
tobiu assigned to @tobiu on Jan 10, 2026, 12:28 PM
tobiu referenced in commit 37a786f - "fix: Implement Service Worker remote method broadcast and replay (#8497)" on Jan 10, 2026, 12:35 PM
tobiu
tobiu Jan 10, 2026, 12:36 PM

Input from tobiu:

◆ Implemented the "Registry & Replay" pattern for Service Worker remote method registration.

Changes:

  1. src/core/Base.mjs (initRemote):

    • Added detection for Neo.workerId === 'service'.
    • Now populates Neo.currentWorker.remotesToRegister with remote.app definitions instead of relying solely on promiseRemotes immediate execution.
  2. src/worker/ServiceBase.mjs:

    • Added remotesToRegister array.
    • Updated createMessageChannel to iterate through remotesToRegister and post registerRemote messages to the newly connected port. This ensures every connecting client (tab) receives the remote method proxies.
    • Refined hasWorker(name) to strict mode (!!this.getPort(name) || !!this.lastClient), removing the hardcoded name === 'app' check. This prevents promiseRemotes from falsely attempting to send messages when no clients are actually connected, preventing initialization errors.

This ensures robust remote method availability across all connected windows and tabs.

tobiu closed this issue on Jan 10, 2026, 12:36 PM