mirror of
https://github.com/ajnart/homarr.git
synced 2026-02-28 01:10:54 +01:00
feat: add trpc websocket (#205)
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import "server-only";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { observable } from "@trpc/server/observable";
|
||||
|
||||
import { createSalt, hashPassword } from "@homarr/auth";
|
||||
import type { Database } from "@homarr/db";
|
||||
@@ -99,6 +98,15 @@ export const userRouter = createTRPCRouter({
|
||||
})
|
||||
.where(eq(users.id, input.userId));
|
||||
}),
|
||||
test: publicProcedure.subscription(() => {
|
||||
return observable<number>((emit) => {
|
||||
let counter = 0;
|
||||
setInterval(() => {
|
||||
counter = counter + 1;
|
||||
emit.next(counter);
|
||||
}, 1000);
|
||||
});
|
||||
}),
|
||||
});
|
||||
|
||||
const createUser = async (
|
||||
|
||||
@@ -12,6 +12,7 @@ import superjson from "superjson";
|
||||
import type { Session } from "@homarr/auth";
|
||||
import { auth } from "@homarr/auth";
|
||||
import { db } from "@homarr/db";
|
||||
import { logger } from "@homarr/log";
|
||||
import { ZodError } from "@homarr/validation";
|
||||
|
||||
/**
|
||||
@@ -33,7 +34,10 @@ export const createTRPCContext = async (opts: {
|
||||
const session = opts.session ?? (await auth());
|
||||
const source = opts.headers.get("x-trpc-source") ?? "unknown";
|
||||
|
||||
console.log(">>> tRPC Request from", source, "by", session?.user);
|
||||
logger.info(
|
||||
`tRPC request from ${source} by user '${session?.user.id}'`,
|
||||
session?.user,
|
||||
);
|
||||
|
||||
return {
|
||||
session,
|
||||
|
||||
53
packages/api/src/wssDevServer.ts
Normal file
53
packages/api/src/wssDevServer.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { applyWSSHandler } from "@trpc/server/adapters/ws";
|
||||
import { WebSocketServer } from "ws";
|
||||
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
import { appRouter } from "./root";
|
||||
import { createTRPCContext } from "./trpc";
|
||||
|
||||
const wss = new WebSocketServer({
|
||||
port: 3001,
|
||||
});
|
||||
const handler = applyWSSHandler({
|
||||
wss,
|
||||
router: appRouter,
|
||||
createContext: ({ req }) => {
|
||||
return createTRPCContext({
|
||||
headers: {
|
||||
...req.headers,
|
||||
get(key: string) {
|
||||
const item = req.headers[key];
|
||||
return typeof item === "string" ? item ?? null : item?.at(0) ?? null;
|
||||
},
|
||||
} as Headers,
|
||||
session: {
|
||||
// TODO: replace with actual session
|
||||
user: {
|
||||
id: "1",
|
||||
name: "Test User",
|
||||
email: "",
|
||||
},
|
||||
expires: new Date().toISOString(),
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
wss.on("connection", (ws, incomingMessage) => {
|
||||
logger.info(
|
||||
`➕ Connection (${wss.clients.size}) ${incomingMessage.method} ${incomingMessage.url}`,
|
||||
);
|
||||
ws.once("close", (code, reason) => {
|
||||
logger.info(
|
||||
`➖ Connection (${wss.clients.size}) ${code} ${reason.toString()}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
logger.info("✅ WebSocket Server listening on ws://localhost:3001");
|
||||
|
||||
process.on("SIGTERM", () => {
|
||||
logger.info("SIGTERM");
|
||||
handler.broadcastReconnectNotification();
|
||||
wss.close();
|
||||
});
|
||||
Reference in New Issue
Block a user