Множественная отправка сообщений через WebSocket
Пишу онлайн чат на Spring WebSocket и ReactJs.
Проблема в дублировании сообщения при отправке, при чем с каждым новым сообщением дубликатов все больше.
Код:
const Message = () => {
const dispatch = useDispatch();
const { message, auth } = useSelector((store) => store);
const [currentChat, setCurrentChat] = useState();
const [messages, setMessages] = useState([]);
const [selectedImage, setSelectedImage] = useState();
const [isLoading, setIsLoading] = useState(false);
const chatContainerRef = useRef(null);
const stompClientRef = useRef(null);
useEffect(() => {
dispatch(getAllChats());
}, [message.message]);
const handleSelectImage = async (e) => {
setIsLoading(true);
console.log("select image");
const imgUrl = await uploadToCloud(e.target.files[0], "image");
setSelectedImage(imgUrl);
setIsLoading(false);
};
const handleCreateMessage = (value) => {
const message = {
chatId: currentChat?.id,
content: value,
image: selectedImage,
};
dispatch(createMessage({ message, sendMessageToServer }));
};
useEffect(() => {
dispatch(getMessagesChat(currentChat?.id))
}, []);
const [stompClient, setStomClient] = useState();
useEffect(() => {
const sock = new SockJS("http://localhost:8080/ws");
const stomp = Stomp.over(sock);
setStomClient(stomp);
stomp.connect({}, onConnect, onErr);
}, []);
const onConnect = () => {
//TODO
console.log("websocket connected...");
};
const onErr = (error) => {
//TODO
console.log("errr", error);
};
useEffect(() => {
if (stompClient && auth.user && currentChat) {
const subscription = stompClient.subscribe(
`/user/${currentChat.id}/private`,
onMessageReceive
);
}
});
const sendMessageToServer = (newMessage) => {
if (stompClient && newMessage) {
stompClient.send(
`/app/chat/${currentChat?.id.toString()}`,
{},
JSON.stringify(newMessage)
);
}
};
const onMessageReceive = (payload) => {
const recivedMessage = JSON.parse(payload.body);
console.log("message revice from websocket", recivedMessage);
setMessages((prevMessages) => [...prevMessages, recivedMessage]);
};
useEffect(() => {
if (chatContainerRef.current) {
chatContainerRef.current.scrollTop =
chatContainerRef.current.scrollHeight;
}
}, [messages]);
В базе данных все отлично, сохраняется в одном экземпляре, также если обновить страницу то все сообщения отображаются корректно по одному. Надеюсь на Вашу помощь, только начал осваивать Реакт и ВебСокет.
Ответы (1 шт):
Автор решения: Владислав Карпенко
→ Ссылка
Решение - проверять наличие подписки
const [isSubscribed, setIsSubscribed] = useState(false);
useEffect(() => {
if (stompClient && auth.user && currentChat && !isSubscribed) {
const subscription = stompClient.subscribe(
`/user/${currentChat.id}/private`,
onMessageReceive
);
setIsSubscribed(true);
}
});