continue dispatch-server
This commit is contained in:
8
apps/dispatch-server/.d.ts
vendored
Normal file
8
apps/dispatch-server/.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
declare module "next-auth/jwt" {
|
||||
interface JWT {
|
||||
uid: string;
|
||||
firstname: string;
|
||||
lastname: string;
|
||||
email: string;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
PORT=3002
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PORT=6379
|
||||
DISPATCH_APP_TOKEN=
|
||||
@@ -3,27 +3,23 @@ import express from "express";
|
||||
import { createServer } from "http";
|
||||
import { handle } from "socket-events/connect-dispatch";
|
||||
import { Server } from "socket.io";
|
||||
import { createClient } from "redis";
|
||||
import { createAdapter } from "@socket.io/redis-adapter";
|
||||
|
||||
const pubClient = createClient();
|
||||
const subClient = pubClient.duplicate();
|
||||
import { jwtMiddleware } from "modules/socketJWT";
|
||||
import { pubClient, subClient } from "modules/redis";
|
||||
|
||||
const app = express();
|
||||
const server = createServer(app);
|
||||
|
||||
const initApp = async () => {
|
||||
await Promise.all([pubClient.connect(), subClient.connect()]);
|
||||
const io = new Server(server, {
|
||||
adapter: createAdapter(pubClient, subClient),
|
||||
});
|
||||
const io = new Server(server, {
|
||||
adapter: createAdapter(pubClient, subClient),
|
||||
cors: {},
|
||||
});
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
socket.on("connect-dispatch", handle);
|
||||
});
|
||||
server.listen(process.env.PORT, () => {
|
||||
console.log(`Server running on port ${process.env.PORT}`);
|
||||
});
|
||||
};
|
||||
io.use(jwtMiddleware);
|
||||
|
||||
initApp();
|
||||
io.on("connection", (socket) => {
|
||||
socket.on("connect-dispatch", () => {});
|
||||
});
|
||||
server.listen(process.env.PORT, () => {
|
||||
console.log(`Server running on port ${process.env.PORT}`);
|
||||
});
|
||||
|
||||
8
apps/dispatch-server/modules/redis.ts
Normal file
8
apps/dispatch-server/modules/redis.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { createClient } from "redis";
|
||||
|
||||
export const pubClient = createClient();
|
||||
export const subClient = pubClient.duplicate();
|
||||
|
||||
Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
|
||||
console.log("Redis connected");
|
||||
});
|
||||
28
apps/dispatch-server/modules/socketJWT.ts
Normal file
28
apps/dispatch-server/modules/socketJWT.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { ExtendedError, Server, Socket } from "socket.io";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { pubClient } from "modules/redis";
|
||||
|
||||
if (!process.env.DISPATCH_APP_TOKEN)
|
||||
throw new Error("DISPATCH_APP_TOKEN is not defined");
|
||||
|
||||
export const jwtMiddleware = async (
|
||||
socket: Socket,
|
||||
next: (err?: ExtendedError) => void,
|
||||
) => {
|
||||
try {
|
||||
const token = socket.handshake.auth?.token;
|
||||
console.log(socket.handshake);
|
||||
if (!token) return new Error("Authentication error");
|
||||
const decoded = jwt.verify(token, process.env.DISPATCH_APP_TOKEN!);
|
||||
// socket.data.userId = decoded.; // User ID lokal speichern
|
||||
|
||||
// Prüfen, ob der Nutzer ein Disponent ist
|
||||
const userId: any = decoded;
|
||||
socket.data.user = decoded; // Lokal speichern
|
||||
|
||||
// In Redis speichern: Key = 'connected_dispatchers', Feld = socket.id, Wert = JSON-String des Users
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
next(new Error("Authentication error"));
|
||||
}
|
||||
};
|
||||
@@ -24,6 +24,7 @@
|
||||
"cron": "^4.1.0",
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^4.21.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"nodemailer": "^6.10.0",
|
||||
"react": "^19.0.0",
|
||||
"redis": "^4.7.0",
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { pubClient } from "modules/redis";
|
||||
import { Server, Socket } from "socket.io";
|
||||
|
||||
export const handle = async (socket: Socket, io: Server) => {
|
||||
console.log("Connected to dispatch server");
|
||||
socket.on("disconnect", () => {
|
||||
export const handle = (socket: Socket, io: Server) => async (jwt: string) => {
|
||||
const userId = socket.data.user.id; // User ID aus dem JWT-Token
|
||||
await pubClient.set(`dispatchers:${socket.id}`, userId);
|
||||
|
||||
socket.join("dispatchers"); // Dem Dispatcher-Raum beitreten
|
||||
|
||||
socket.on("disconnect", async () => {
|
||||
console.log("Disconnected from dispatch server");
|
||||
await pubClient.del(`dispatchers:${socket.id}`);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,8 +3,13 @@ import { ToggleTalkButton } from "../_components/ToggleTalkButton";
|
||||
import { ChangeRufgruppe } from "../_components/ChangeRufgruppe";
|
||||
import { Notifications } from "../_components/Notifications";
|
||||
import Link from "next/link";
|
||||
import { connectionStore } from "../../_store/connectionStore";
|
||||
import { useEffect } from "react";
|
||||
import { socket } from "../socket";
|
||||
|
||||
export default function Navbar() {
|
||||
const connected = connectionStore((state) => state);
|
||||
|
||||
return (
|
||||
<div className="navbar bg-base-100 shadow-sm">
|
||||
<div className="flex-1">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { Metadata } from "next";
|
||||
import Navbar from "./_components/Navbar";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { getServerSession } from "../api/auth/[...nextauth]/auth";
|
||||
|
||||
|
||||
7
apps/dispatch/app/(dispatch)/socket.ts
Normal file
7
apps/dispatch/app/(dispatch)/socket.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { io } from "socket.io-client";
|
||||
|
||||
export const socket = io(process.env.NEXT_PUBLIC_DISPATCH_SERVER_URL, {
|
||||
auth: (cb) => {
|
||||
cb({ token: "jwt" });
|
||||
},
|
||||
});
|
||||
16
apps/dispatch/app/_store/connectionStore.ts
Normal file
16
apps/dispatch/app/_store/connectionStore.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { create } from "zustand";
|
||||
import { socket } from "../(dispatch)/socket";
|
||||
|
||||
console.log("connectionStore");
|
||||
|
||||
export const connectionStore = create((set) => ({
|
||||
isConnected: false,
|
||||
connect: async (jwt: string) => {
|
||||
socket.auth = { token: "jwt" };
|
||||
socket.connect();
|
||||
},
|
||||
}));
|
||||
|
||||
socket.on("connect", () => {
|
||||
connectionStore.setState({ isConnected: true });
|
||||
});
|
||||
9
apps/dispatch/app/_store/stationsStore.ts
Normal file
9
apps/dispatch/app/_store/stationsStore.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { create } from "zustand";
|
||||
import { socket } from "../(dispatch)/socket";
|
||||
|
||||
export const stationStore = create((set) => {
|
||||
return {
|
||||
stations: [],
|
||||
setStations: (stations: any) => set({ stations }),
|
||||
};
|
||||
});
|
||||
@@ -20,6 +20,7 @@
|
||||
"postcss": "^8.5.1",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"socket.io-client": "^4.8.1",
|
||||
"tailwindcss": "^4.0.2",
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user