While trying to implement subscriptions with tRPC, I encountered this issue, that it should use wsLink, even though, it is implemented in the trpc client.
I get this error when trying to use randomNumber router, here is my code:
This is my wssDevServer.ts file
/src/server/wssDevServer.ts
const wss = new ws.Server({
port: 3001
})
const handler = applyWSSHandler({
wss,
router: appRouter,
createContext,
// Enable heartbeat messages to keep connection open (disabled by default)
keepAlive: {
enabled: true,
// server ping message interval in milliseconds
pingMs: 30000,
// connection is terminated if pong message is not received in this many milliseconds
pongWaitMs: 5000
}
})
wss.on('connection', ws => {
console.log(`➕➕ Connection (${wss.clients.size})`)
ws.once('close', () => {
console.log(`➖➖ Connection (${wss.clients.size})`)
})
})
console.log('✅ WebSocket Server listening on ws://localhost:3001')
process.on('SIGTERM', () => {
console.log('SIGTERM')
handler.broadcastReconnectNotification()
wss.close()
})
This is my trpc client:
//utils/trpc.ts
// const { publicRuntimeConfig } = getConfig()
// const { APP_URL, WS_URL } = publicRuntimeConfig
function getEndingLink(ctx: NextPageContext | undefined): TRPCLink<AppRouter> {
if (typeof window === 'undefined') {
return httpBatchLink({
/**
* @link https://trpc.io/docs/v11/data-transformers
*/
transformer: superjson,
url: `http://localhost:3000/api/trpc`,
headers() {
if (!ctx?.req?.headers) {
return {}
}
// on ssr, forward client's headers to the server
return {
...ctx.req.headers,
'x-ssr': '1'
}
}
})
}
const client = createWSClient({
url: 'ws://localhost:300'
})
return wsLink({
client,
/**
* @link https://trpc.io/docs/v11/data-transformers
*/
transformer: superjson
})
}
/**
* A set of strongly-typed React hooks from your `AppRouter` type signature with `createReactQueryHooks`.
* @link https://trpc.io/docs/v11/react#3-create-trpc-hooks
*/
export const trpc = createTRPCNext<AppRouter>({
/**
* @link https://trpc.io/docs/v11/ssr
*/
ssr: true,
ssrPrepass,
config({ ctx }) {
/**
* If you want to use SSR, you need to use the server's full URL
* @link https://trpc.io/docs/v11/ssr
*/
return {
/**
* @link https://trpc.io/docs/v11/client/links
*/
links: [
// adds pretty logs to your console in development and logs errors in production
loggerLink({
enabled: opts =>
(process.env.NODE_ENV === 'development' && typeof window !== 'undefined') ||
(opts.direction === 'down' && opts.result instanceof Error)
}),
getEndingLink(ctx)
],
/**
* @link https://tanstack.com/query/v5/docs/reference/QueryClient
*/
queryClientConfig: { defaultOptions: { queries: { staleTime: 60 } } }
}
},
/**
* @link https://trpc.io/docs/v11/data-transformers
*/
transformer: superjson
})
// export const transformer = superjson;
/**
* This is a helper method to infer the output of a query resolver
* @example type HelloOutput = RouterOutputs['hello']
*/
export type RouterOutputs = inferRouterOutputs<AppRouter>
Note that i launch the wssDevServer with this command:
cross-env PORT=3001 tsx watch src/server/wssDevServer.ts --tsconfig tsconfig.server.json
In my appRouter, I have this procedure:
randomNumber: publicProcedure.subscription(() => {
return observable<number>(emit => {
const int = setInterval(() => {
emit.next(Math.random())
}, 500)
return () => {
clearInterval(int)
}
})
}),
Which causes the Error “Subscriptions should use wsLink” using tRPC, any suggestions to solve this issue? Thanks.