From 1a5eafecdbac0041bace3c63435c40ec74a18d81 Mon Sep 17 00:00:00 2001 From: BYEONGRYEOL Date: Thu, 28 Dec 2023 15:56:40 +0900 Subject: [PATCH] =?UTF-8?q?chat=20token=EC=9D=84=20=EB=A8=BC=EC=A0=80=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=ED=95=9C=20=ED=9B=84=20chat=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=EC=97=90=20websocket=20=EC=97=B0=EA=B2=B0=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Chat.js | 159 ++++++++++++++++++++++--------------- src/pages/ChannelDetail.js | 29 +++---- 2 files changed, 107 insertions(+), 81 deletions(-) diff --git a/src/components/Chat.js b/src/components/Chat.js index 85bbadc..bd6da16 100644 --- a/src/components/Chat.js +++ b/src/components/Chat.js @@ -1,5 +1,5 @@ -import React, { useEffect, useState, useRef } from 'react'; -import styled from 'styled-components'; +import React, { useEffect, useState, useRef } from "react"; +import styled from "styled-components"; const ChatContainer = styled.div` border: 1px solid #ccc; @@ -23,13 +23,13 @@ const Sender = styled.span` color: #c0c0c0; font-size: 1rem; padding-left: 5px; - font-family: 'Gamja Flower', sans-serif; + font-family: "Gamja Flower", sans-serif; `; const SpanText = styled.span` font-size: 1.1rem; color: #666; - font-family: 'Gamja Flower', sans-serif; + font-family: "Gamja Flower", sans-serif; `; const InputContainer = styled.div` @@ -50,7 +50,7 @@ const TextInput = styled.input` `; const SendButton = styled.button` - font-family: 'Gamja Flower', sans-serif; + font-family: "Gamja Flower", sans-serif; border-radius: 10px; width: 20%; height: 50%; @@ -61,89 +61,118 @@ const SendButton = styled.button` cursor: pointer; `; -const ChatComponent = ({ chatToken, chattingRoomId }) => { +const ChatComponent = ({ chattingRoomId }) => { const [messages, setMessages] = useState([]); - const [inputMessage, setInputMessage] = useState(''); + const [inputMessage, setInputMessage] = useState(""); const [socket, setSocket] = useState(null); - const tokenString = chatToken; const messagesEndRef = useRef(null); + const chattingRoomIdString = chattingRoomId; + const accessToken = localStorage.getItem("accessToken"); + const fetchToken = async () => { + try { + console.log(accessToken); + const response = await fetch("http://localhost:8081/api/auth/chat", { + method: "POST", + headers: { + Authorization: accessToken, + }, + }); + if (!response.ok) { + throw new Error("Network response was not ok."); + } + const data = await response.json(); + console.log("서버에서 받은 chatTokenResponseDto : ", data); + return data.chatToken; + } catch (error) { + console.error("데이터를 불러오는 중 오류가 발생했습니다:", error); + } + }; + useEffect(() => { // window.addEventListener("beforeunload", () => { // socket.close(); // }); - const chattingRoomIdString = chattingRoomId; - const accessToken = localStorage.getItem('accessToken'); - - const newSocket = new WebSocket( - `ws://localhost:8082/chat/${chattingRoomIdString}/${tokenString}` - ); - setSocket(newSocket); - newSocket.onopen = () => { - console.log('웹소켓 연결됨'); + // chatting 토큰을 먼저 요청하고 나서 webSocket 연결하기 위한 로직 + const connectWebSocketAsync = async () => { + let chatToken = ""; + console.log("accessToken is null ? :", accessToken === null); + if (accessToken) { + chatToken = await fetchToken(); + } else { + chatToken = "notlogin"; // 로그인하지 않은 사용자의 경우 토큰 정보를 notlogin으로 요청한다. + } + const newSocket = new WebSocket( + `ws://localhost:8082/chat/${chattingRoomIdString}/${chatToken}` + ); + setSocket(newSocket); + newSocket.onopen = () => { + console.log("웹소켓 연결됨"); + }; + + newSocket.onmessage = (event) => { + console.log(event.data); + const receiveData = event.data.split(":"); + const from = receiveData[0]; + const message = receiveData.slice(1).join(":").trim(); + setMessages((prevMessages) => [...prevMessages, { from, message }]); + }; + + newSocket.onclose = () => { + console.log("웹소켓 연결 종료"); + // 연결 종료 시 재연결 시도 + setTimeout(async () => { + console.log("accessToken", accessToken); + const response = await fetch("http://localhost:8081/api/auth/chat", { + method: "POST", + headers: { + Authorization: accessToken, + }, + }); + + // 응답에서 토큰 추출 + const tokenString = response.data.chatToken; + const reconnectSocket = new WebSocket( + `ws://localhost:8082/chat/${chattingRoomIdString}/${tokenString}` + ); + reconnectSocket.onopen = () => { + console.log("웹소켓 재연결됨"); + setSocket(reconnectSocket); + }; + + reconnectSocket.onmessage = (event) => { + console.log(event.data); + const receiveData = event.data.split(":"); + const from = receiveData[0]; + const message = receiveData.slice(1).join(":").trim(); + setMessages((prevMessages) => [...prevMessages, { from, message }]); + }; + }, 3000); // 3초 후 재연결 시도 + }; + return () => { + newSocket.close(); + }; }; - newSocket.onmessage = (event) => { - console.log(event.data); - const receiveData = event.data.split(':'); - const from = receiveData[0]; - const message = receiveData.slice(1).join(':').trim(); - setMessages((prevMessages) => [...prevMessages, { from, message }]); - }; - - newSocket.onclose = () => { - console.log('웹소켓 연결 종료'); - // 연결 종료 시 재연결 시도 - setTimeout(async () => { - console.log('accessToken', accessToken); - const response = await fetch('http://localhost:8081/api/auth/chat', { - method: 'POST', - headers: { - Authorization: accessToken, - }, - }); - - // 응답에서 토큰 추출 - const tokenString = response.data.chatToken; - const reconnectSocket = new WebSocket( - `ws://localhost:8082/chat/${chattingRoomIdString}/${tokenString}` - ); - reconnectSocket.onopen = () => { - console.log('웹소켓 재연결됨'); - setSocket(reconnectSocket); - }; - - reconnectSocket.onmessage = (event) => { - console.log(event.data); - const receiveData = event.data.split(':'); - const from = receiveData[0]; - const message = receiveData.slice(1).join(':').trim(); - setMessages((prevMessages) => [...prevMessages, { from, message }]); - }; - }, 3000); // 3초 후 재연결 시도 - }; - - return () => { - newSocket.close(); - }; + connectWebSocketAsync(); }, []); const scrollToBottom = () => { - messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); }; useEffect(scrollToBottom, [messages]); const sendMessage = () => { - if (inputMessage.trim() === '') return; + if (inputMessage.trim() === "") return; socket.send(inputMessage); - setInputMessage(''); + setInputMessage(""); }; const handleKeyDown = (event) => { - if (event.key === 'Enter') { + if (event.key === "Enter") { event.preventDefault(); sendMessage(); } @@ -162,7 +191,7 @@ const ChatComponent = ({ chatToken, chattingRoomId }) => { setInputMessage(e.target.value)} onKeyDown={handleKeyDown} diff --git a/src/pages/ChannelDetail.js b/src/pages/ChannelDetail.js index f209c20..91faf4d 100644 --- a/src/pages/ChannelDetail.js +++ b/src/pages/ChannelDetail.js @@ -1,9 +1,9 @@ -import React, { useEffect, useState } from 'react'; -import { useParams } from 'react-router-dom'; -import Header from '../components/header'; -import VideoPlayer from '../components/ReactPlayer'; -import styled from 'styled-components'; -import Chat from '../components/Chat'; +import React, { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; +import Header from "../components/header"; +import VideoPlayer from "../components/ReactPlayer"; +import styled from "styled-components"; +import Chat from "../components/Chat"; const StreamingContainer = styled.div` width: 100%; @@ -20,7 +20,7 @@ const StreamingTitle = styled.p` margin-top: 15px; margin-left: 15px; font-size: 1.5rem; - font-family: 'Gamja Flower', sans-serif; + font-family: "Gamja Flower", sans-serif; `; const ChatWrapper = styled.div` @@ -39,15 +39,15 @@ const ChannelDetail = () => { `http://localhost:8081/api/channels/${id}` ); if (!response.ok) { - throw new Error('Network response was not ok.'); + throw new Error("Network response was not ok."); } const data = await response.json(); setChannelData(data); - console.log('title:', data.title); - console.log('url:', data.hlsUrl); - console.log('roomid:', data.chattingRoomId); + console.log("title:", data.title); + console.log("url:", data.hlsUrl); + console.log("roomid:", data.chattingRoomId); } catch (error) { - console.error('데이터를 불러오는 중 오류가 발생했습니다:', error); + console.error("데이터를 불러오는 중 오류가 발생했습니다:", error); } }; @@ -61,10 +61,7 @@ const ChannelDetail = () => { {channelData ? : null} {channelData ? ( - + ) : null}