-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
[feat/#2] 실시간 채팅 기본 구현(로컬)
- Loading branch information
Showing
8 changed files
with
279 additions
and
7 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import React from "react"; | ||
import "./css/ChatMessage.css"; | ||
|
||
const ChatMessage = ({ nickname, message, time }) => { | ||
return ( | ||
<div className="chat-message"> | ||
<span className="user-nickname">{nickname}</span> | ||
<div className="message-bubble">{message}</div> | ||
<span className="message-time">{time}</span> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ChatMessage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import React, { useState, useEffect } from "react"; | ||
import ChatMessage from "./ChatMessage"; | ||
import { Client } from '@stomp/stompjs'; | ||
import "./css/ChatScreen.css"; | ||
|
||
const ChatScreen = () => { | ||
const [messages, setMessages] = useState([]); | ||
const [client, setClient] = useState(null); | ||
const [inputMessage, setInputMessage] = useState(""); | ||
|
||
const handleMessage = (message) => { | ||
console.log("받은 메시지: ", message.body); // 메시지 확인용 로그 | ||
const body = JSON.parse(message.body); | ||
|
||
// ID를 사용하여 중복 확인 | ||
const existingMessage = messages.find(msg => msg.id === body.id); | ||
if (!existingMessage) { | ||
setMessages(prevMessages => { | ||
const updatedMessages = [...prevMessages, body]; | ||
console.log("업데이트된 messages 상태: ", updatedMessages); // 상태 업데이트 확인용 로그 | ||
return updatedMessages; | ||
}); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
if (!client) { | ||
const newClient = new Client({ | ||
brokerURL: "ws://localhost:8080/ws", | ||
debug: function (str) { | ||
console.log(str); | ||
}, | ||
reconnectDelay: 5000, | ||
heartbeatIncoming: 4000, | ||
heartbeatOutgoing: 4000, | ||
}); | ||
|
||
newClient.onConnect = () => { | ||
console.log("웹소켓 연결 성공"); | ||
setClient(newClient); | ||
|
||
newClient.subscribe('/sub/public', (message) => { | ||
handleMessage(message); | ||
}); | ||
}; | ||
|
||
newClient.onStompError = (error) => { | ||
console.error("웹소켓 연결 에러:", error); | ||
}; | ||
|
||
newClient.activate(); | ||
} | ||
|
||
return () => { | ||
if (client && client.connected) { | ||
client.deactivate(); | ||
} | ||
}; | ||
}, [client]); | ||
|
||
useEffect(() => { | ||
console.log("렌더링된 messages 상태: ", messages); // 상태 변화 확인용 로그 | ||
}, [messages]); | ||
|
||
const sendMessage = () => { | ||
if (client && client.connected) { | ||
const chatMessage = { | ||
type: "MESSAGE", | ||
content: inputMessage, | ||
sender: "사용자 닉네임", | ||
time: new Date().toISOString() | ||
}; | ||
|
||
console.log("보내는 메시지: ", chatMessage); // 메시지 전송 확인용 로그 | ||
client.publish({ | ||
destination: '/pub/chat.sendMessage', | ||
body: JSON.stringify(chatMessage), | ||
}); | ||
setInputMessage(""); | ||
} else { | ||
console.error("STOMP 연결 실패"); | ||
} | ||
}; | ||
|
||
return ( | ||
<div className="chat-screen"> | ||
<div className="chat-messages"> | ||
{messages.map((message, index) => { | ||
console.log("렌더링할 메시지: ", message); // 렌더링 확인용 로그 | ||
return ( | ||
<ChatMessage | ||
key={index} | ||
nickname={message.sender} | ||
message={message.content} | ||
time={new Date(message.time).toLocaleString()} // ISO 8601 형식을 파싱하여 표시 | ||
/> | ||
); | ||
})} | ||
</div> | ||
<div className="chat-input"> | ||
<input | ||
className="chat-input-box" | ||
type="text" | ||
placeholder="메시지를 입력하세요." | ||
value={inputMessage} | ||
onChange={(e) => setInputMessage(e.target.value)} | ||
/> | ||
<button | ||
className="chat-input-button" | ||
aria-label="전송" | ||
onClick={sendMessage} | ||
> | ||
|
||
</button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default ChatScreen; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
.chat-message { | ||
width: 345px; | ||
height: auto; | ||
flex-shrink: 0; | ||
} | ||
|
||
.user-nickname { | ||
width: 345px; | ||
height: 15.14px; | ||
flex-shrink: 0; | ||
font-family: "Pretendard-Regular"; | ||
font-size: 12px; | ||
font-weight: 400; | ||
line-height: 1.3333; /* 16px */ | ||
} | ||
|
||
.message-bubble { | ||
width: 372px; | ||
height: auto; | ||
flex-shrink: 0; | ||
border-radius: 12px 12px 12px 0px; | ||
background: #F7F7F7; | ||
color: #626264; | ||
text-align: left; | ||
font-family: "Pretendard-Regular"; | ||
font-size: 12px; | ||
font-weight: 400; | ||
line-height: 16px; | ||
padding: 8px; | ||
margin-top: 5px; | ||
} | ||
|
||
.message-time { | ||
font-family: "Pretendard-Regular"; | ||
font-size: 12px; | ||
font-weight: 400; | ||
line-height: 16px; | ||
text-align: right; | ||
display: block; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
.chat-screen { | ||
width: 915px; | ||
height: 700px; | ||
flex-shrink: 0; | ||
background-color: white; | ||
border: 1px solid #ccc; | ||
border-radius: 10px; | ||
overflow-y: auto; | ||
padding: 10px; | ||
margin-left: 20px; | ||
position: relative; | ||
} | ||
|
||
.chat-message { | ||
width: auto; | ||
height: auto; | ||
} | ||
|
||
.chat-messages { | ||
width: 100%; | ||
height: 100%; | ||
overflow-y: auto; | ||
margin-bottom: 10px; | ||
} | ||
|
||
|
||
.chat-input { | ||
width: 785px; | ||
height: 48px; | ||
flex-shrink: 0; | ||
border-radius: 8px; | ||
background: #F7F7F7; | ||
position: absolute; | ||
bottom: 63px; | ||
left: 50%; | ||
transform: translateX(-50%); | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
padding: 0 10px; | ||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||
} | ||
|
||
|
||
.chat-input input { | ||
flex: 1; | ||
border: none; | ||
outline: none; | ||
background: none; | ||
height: 100%; | ||
padding: 0 10px; | ||
font-size: 16px; | ||
border-radius: 8px 0 0 8px; | ||
} | ||
|
||
.chat-input button { | ||
width: 48px; | ||
height: 48px; | ||
flex-shrink: 0; | ||
border-radius: 10px; | ||
background: #47ABD9 url("/src/assets/images/ic_chat_send.png") no-repeat center; | ||
background-size: 24px; | ||
border: none; | ||
cursor: pointer; | ||
margin-left: 15px; | ||
} | ||
|
||
.chat-input button:hover { | ||
background-color: #0056b3; | ||
} | ||
|