import { useEffect, useRef } from "react"; import * as signalR from "@microsoft/signalr"; import { useRealtimeClient } from "@/components/Provider/RealtimeClientProvider"; import { useToast } from "@/hooks/use-toast"; export const useSignalRConnection = (params: { access_token: string; roomId: string; }) => { const connectionRef = useRef(null); const { handleDisconnect } = useRealtimeClient(); const { toast } = useToast(); const timerRef = useRef(null); useEffect(() => { if (!params.access_token || !params.roomId) { return; } const connection = new signalR.HubConnectionBuilder() .withServerTimeout(30000) .withAutomaticReconnect() .withUrl( `https://api.v3.ycymedu.com/hubs/weminpro?access_token=${params.access_token}&roomId=${params.roomId}` ) .configureLogging(signalR.LogLevel.Information) .build(); connectionRef.current = connection; connection.on("ForceOffline", function (msg) { // 可加逻辑:注销用户、跳转登录页等 toast({ variant: "destructive", title: "下线提醒", description: msg, }); handleDisconnect(); }); connection.on("SendWarn", function (msg) { console.warn(`下线提醒:${msg}"`); // 也可以弹窗提醒用户保存数据 toast({ variant: "destructive", title: "下线提醒", description: msg, }); }); connection .start() .then(() => { console.log("SignalR连接已建立"); timerRef.current = setInterval(() => { connection.invoke("Ping"); }, 5000); }) .catch((err) => { console.error("SignalR连接失败:", err); }); return () => { if (connectionRef.current) { connectionRef.current .stop() .then(() => { clearInterval(timerRef.current as NodeJS.Timeout); console.log("SignalR连接已关闭"); }) .catch((err) => { console.error("关闭SignalR连接失败:", err); }); } }; }, [params.access_token, params.roomId]); return connectionRef.current; };