Skip to content

Socket Transport

Socket transport is useful when host and remote are not in the same browser context and you need a network boundary:

  • remote runtime runs in another process or machine;
  • you need live remote sessions for extension development;
  • you want debugger/observer clients to connect independently.

@omnicajs/vue-remote keeps render synchronization as a channel contract. Socket transport is an implementation choice for delivering that contract over the network.

Compared to iframe/worker transport, this mode adds operational responsibilities:

  • session lifecycle across reconnects;
  • auth and capability checks;
  • message ordering and idempotency;
  • payload limits and redaction policies.
Host Runtime
-> createReceiver()
-> createEndpoint(fromSocket(...))
-> call.run(receiver.receive, hostBridge)
Socket Gateway
-> session routing (host <-> remote)
-> auth + protocol version checks
Remote Runtime
-> createEndpoint(fromSocket(...))
-> expose run/release

Minimal MessageEndpoint wrapper over WebSocket

Section titled “Minimal MessageEndpoint wrapper over WebSocket”

@remote-ui/rpc works with objects implementing MessageEndpoint. You can adapt WebSocket to that shape:

import type { MessageEndpoint } from '@remote-ui/rpc'
export function fromSocket(socket: WebSocket): MessageEndpoint {
const listeners = new Set<(event: MessageEvent) => void>()
socket.addEventListener('message', (event) => {
const message = JSON.parse(event.data as string)
const wrapped = { data: message } as MessageEvent
for (const listener of listeners) {
listener(wrapped)
}
})
return {
postMessage(message: any) {
socket.send(JSON.stringify(message))
},
addEventListener(event, listener) {
if (event === 'message') {
listeners.add(listener)
}
},
removeEventListener(event, listener) {
if (event === 'message') {
listeners.delete(listener)
}
},
terminate() {
socket.close()
},
}
}

Then wire endpoints exactly like other transports:

const socket = new WebSocket('wss://runtime.example.com/remote-session?sessionId=abc')
const endpoint = createEndpoint<RemoteApi>(fromSocket(socket))
await endpoint.call.run(receiver.receive, hostBridge)
  1. Authenticate every session before run(...).
  2. Version protocol and reject incompatible clients.
  3. Enforce ordering/correlation IDs at gateway level.
  4. Add reconnect policy with explicit session resume rules.
  5. Apply payload size limits and sensitive-field redaction.
  • Good fit for advanced extension platforms and remote debugging.
  • Overkill for basic single-page host + extension setups.

For browser-local setups, prefer Web Worker Runtime or iframe transport first.