The Docs.

Prim+RPC is in prerelease mode and may be unstable until official release.
All Plugins

ws

Plugin Details
  • Plugin Type:
    Callback Handler
  • Transport:
    WebSocket
  • Works with:

Prim+RPC can communicate over WebSocket for easy support of callback defined on your methods. You may either use the WebSockets alone as a callback handler with Prim+RPC (always upgrade HTTP to a WebSocket connection) or use both an HTTP server (some method handler in Prim+RPC) and WebSocket server together, only upgrading to a WebSocket connection when it’s actually needed: Prim+RPC will know when to do so. We’ll cover both scenarios:

In both cases, we’ll use the same module with Prim+RPC, which will simply type each letter of the message that we give it over a callback:

export function hello(message: string, callback: (letter: string) => void) {
	let timeout = 0
	for (const letter of message.split("")) {
		setTimeout(() => callback(letter), ++timeout * 300)
	}
}
hello.rpc = true
 
export default hello

WebSocket Alone

You may use Prim+RPC with a WebSocket server only, if needed. In this case, all HTTP requests will be upgraded to a WebSocket connection.

import { createPrimServer } from "@doseofted/prim-rpc"
import { createCallbackHandler } from "@doseofted/prim-rpc-plugins/ws"
import { WebSocketServer } from "ws"
import * as module from "./module"
 
const wss = new WebSocketServer({ port: 3000 })
const callbackHandler = createCallbackHandler({ wss })
 
const prim = createPrimServer({ module, callbackHandler })

Now we can test out using our function from the WebSocket server! We may either set up the corresponding method plugin to test out WebSockets or use command-line tools like wscat to test it out:

$ npx wscat@latest -c ws://localhost:3000/prim
Connected (press CTRL+C to quit)
> { "id": "test", "method": "hello", "args": ["Hi!", "_cb_123"] }
< { "id": "test", "result": null }
< { "id": "_cb_123", "result": ["H"] }
< { "id": "_cb_123", "result": ["i"] }
< { "id": "_cb_123", "result": ["!"] }

Using tools like wscat for testing may require additional knowledge of how Prim+RPC serializes messages.

WebSocket with Existing Server

In this example, we’ll use a method handler that will communicate over HTTP alone and whenever a callback is given, Prim+RPC will upgrade the connection to WebSocket.

First, we’ll set up some method handler with Prim+RPC. You may choose any server that you like. We’ll simply pass the resulting server into ws when setting up the callback handler.

For example, let’s say that we have already set up Prim+RPC with Hono:

import { createPrimServer } from "@doseofted/prim-rpc"
import { createMethodHandler } from "@doseofted/prim-rpc-plugins/hono"
import { Hono } from "hono"
import { serve } from "@hono/node-server"
import * as module from "./module"
 
const app = new Hono()
const server = serve(app)
 
const methodHandler = createMethodHandler({ app })
const prim = createPrimServer({ module, methodHandler })

We can add the callback handler to Prim+RPC by simply passing the server to ws. We can then pass our WebSocket server to Prim+RPC’s callback handler like so:

import { createPrimServer } from "@doseofted/prim-rpc"
import { createMethodHandler } from "@doseofted/prim-rpc-plugins/hono"
import { Hono } from "hono"
import { serve } from "@hono/node-server"
import { WebSocketServer } from "ws"
import { createCallbackHandler } from "@doseofted/prim-rpc-plugins/ws"
import * as module from "./module"
 
const app = new Hono()
const server = serve(app)
const wss = new WebSocketServer({ server })
 
const methodHandler = createMethodHandler({ app })
const callbackHandler = createCallbackHandler({ wss })
 
const prim = createPrimServer({ module, methodHandler, callbackHandler })

Now our WebSocket server is all set up! We can either set up the corresponding method plugin to test out WebSockets or use command-line tools like wscat to test it out:

When using the Prim+RPC client there is no need to understand the RPC structure but for testing with a generic WebSocket client, you may need to know how Prim+RPC serializes callback data. Below is an example session using wscat:

$ npx wscat@latest -c ws://localhost:3000/prim
Connected (press CTRL+C to quit)
> { "id": "test", "method": "hello", "args": ["Hi!", "_cb_123"] }
< { "id": "test", "result": null }
< { "id": "_cb_123", "result": ["H"] }
< { "id": "_cb_123", "result": ["i"] }
< { "id": "_cb_123", "result": ["!"] }

You may also choose a compatible callback plugin:

Report an Issue