fixed code v2

This commit is contained in:
SlimusMinus
2026-08-12 00:38:04 +03:00
parent fe3c91446a
commit e45c9326ed
19 changed files with 233 additions and 124 deletions

View File

@@ -1,60 +1,22 @@
import { useEffect, useRef, useState, useCallback } from "react";
import { Client } from "@stomp/stompjs";
import SockJS from "sockjs-client";
import { API_URL } from "../config/authConstants";
import { getAccessToken, refreshAccessToken } from "../api/apiClient";
// src/hooks/useChatSocket.js
import { useEffect, useRef, useCallback } from "react";
import { useStompClient, parseStompMessage } from "./useStompClient";
export function useChatSocket(chatId, onMessage) {
const clientRef = useRef(null);
const onMessageRef = useRef(onMessage);
const [connected, setConnected] = useState(false);
// Держим актуальный колбэк в ref, чтобы не пересоздавать соединение
// при каждом ре-рендере родителя из-за нового onMessage
useEffect(() => {
onMessageRef.current = onMessage;
}, [onMessage]);
useEffect(() => {
if (!chatId) return;
const client = new Client({
webSocketFactory: () => new SockJS(`${API_URL}/ws`),
reconnectDelay: 3000,
beforeConnect: async () => {
client.connectHeaders = {
Authorization: `Bearer ${getAccessToken()}`,
};
},
onConnect: () => {
setConnected(true);
client.subscribe(`/topic/chat/${chatId}`, (msg) => {
try {
const body = JSON.parse(msg.body);
onMessageRef.current(body);
} catch (e) {
console.error("Failed to parse chat message:", e);
}
});
},
onDisconnect: () => setConnected(false),
onStompError: async (frame) => {
if (frame.headers?.message?.includes("Unauthorized")) {
try {
await refreshAccessToken();
} catch {
// refresh тоже не удался — дальше решает общий логин-флоу (redirect на /)
}
}
},
const handleConnect = useCallback((client) => {
client.subscribe(`/topic/chat/${chatId}`, (msg) => {
parseStompMessage(msg, (body) => onMessageRef.current(body));
});
client.activate();
clientRef.current = client;
return () => client.deactivate();
}, [chatId]);
const { clientRef, connected } = useStompClient(!!chatId, handleConnect);
/** @returns {boolean} true если сообщение реально ушло в сокет, false если соединения нет */
const sendMessage = useCallback((content) => {
if (!clientRef.current?.connected) return false;
@@ -63,7 +25,7 @@ export function useChatSocket(chatId, onMessage) {
body: JSON.stringify({ chatId, content }),
});
return true;
}, [chatId]);
}, [chatId, clientRef]);
return { connected, sendMessage };
}