Skip to content

Commit

Permalink
feat: 웹사이트 접속시 닉네임 입력, 메시지에 닉네임 표시
Browse files Browse the repository at this point in the history
  • Loading branch information
gyehyun-bak committed Jan 7, 2025
1 parent 705a2ca commit 692bff8
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 15 deletions.
73 changes: 62 additions & 11 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,34 @@ interface MessageRequestDto {
interface MessageResponseDto {
content: string;
sessionId: string;
nickname: string;
}

// 서버 웹소켓 엔드포인트트
const SOCKET_URL = "http://localhost:8080/ws";

// 닉네임 최대 길이
const MAX_NICKNAME_LENGTH = 30;

function App() {
const [message, setMessage] = useState("");
const [messages, setMessages] = useState<MessageResponseDto[]>([]);
const [isNicknameEntered, setIsNicknameEntered] = useState(false); // 웹소켓 연결 여부
const [nickname, setNickname] = useState(""); // 웹사이트 접속시 입력받을 세션 닉네임
const [sessionId, setSessionId] = useState(""); // 유저가 보낸 메시지 식별용 Session Id
const stompClientRef = useRef<Client | null>(null);
const inputRef = useRef<HTMLInputElement | null>(null);

useEffect(() => {
if (!isNicknameEntered) return;

const socket = new SockJS(SOCKET_URL);
const stompClient = new Client({
webSocketFactory: () => socket as any,
debug: (msg: string) => console.log("[STOMP]:", msg),
connectHeaders: {
nickname: nickname,
},
onConnect: () => {
// 세션 아이디 추출
const sessionId = (socket as any)._transport.url
Expand Down Expand Up @@ -62,7 +73,7 @@ function App() {
return () => {
stompClient.deactivate();
};
}, []);
}, [isNicknameEntered]);

const sendMessage = () => {
if (
Expand Down Expand Up @@ -91,22 +102,62 @@ function App() {
}
};

const enterNickname = () => {
if (!nickname.trim()) {
setNickname("익명");
}

setIsNicknameEntered(true);
};

if (!isNicknameEntered) {
return (
<div className="flex justify-center w-screen h-screen">
<div className="flex flex-col max-w-screen-sm w-full h-full bg-neutral-50 justify-center px-20 gap-5">
<h1 className="text-2xl font-bold">닉네임을 입력해주세요😀</h1>
<input
type="text"
placeholder="익명"
value={nickname}
maxLength={MAX_NICKNAME_LENGTH}
onChange={(e) => {
setNickname(e.target.value);
}}
className="p-4 rounded-xl shadow-xl"
/>
<div className="text-sm text-gray-400 flex justify-end">
{nickname.length} / {MAX_NICKNAME_LENGTH}
</div>
<button
onClick={enterNickname}
className="bg-blue-600 text-white p-2 rounded-xl shadow-xl"
>
입장
</button>
</div>
</div>
);
}

return (
<div className="flex justify-center w-screen h-screen">
<div className="flex flex-col max-w-screen-sm w-full h-full bg-neutral-50">
{/* Body */}
<div className="flex-1 overflow-auto p-4">
<div className="flex flex-col gap-1">
{messages.map((message, index) => (
<div
key={index}
className={`px-4 py-3 my-1 rounded-xl w-fit shadow-md ${
message.sessionId === sessionId
? "bg-blue-600 text-white self-end" // 자신의 메시지
: "bg-white self-start" // 다른 사람의 메시지
}`}
>
{message.content}
<div className={`flex flex-col gap-1 ${message.sessionId === sessionId ? "items-end" : "items-start"}`}>
<span className="text-sm text-neutral-400">{message.nickname}</span>
<div
key={index}
className={`px-4 py-3 my-1 rounded-xl w-fit shadow-md ${
message.sessionId === sessionId
? "bg-blue-600 text-white self-end" // 자신의 메시지
: "bg-white self-start" // 다른 사람의 메시지
}`}
>
{message.content}
</div>
</div>
))}
</div>
Expand Down Expand Up @@ -135,4 +186,4 @@ function App() {
);
}

export default App;
export default App;
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public class ChatController {
@MessageMapping("/chat")
@SendTo("/topic/chat")
public MessageResponseDto sendChatMessage(MessageRequestDto requestDto, SimpMessageHeaderAccessor accessor) {
return chatService.processMessage(requestDto, accessor.getSessionId());
return chatService.processMessage(requestDto, accessor.getSessionId(), (String) accessor.getSessionAttributes().get("nickname"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.spring_websocket.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.messaging.SessionConnectEvent;

@Component
@RequiredArgsConstructor
@Slf4j
public class WebSocketHandler {
/**
* STOMP 서브 프로토콜을 통한 CONNECT 메시지가 수신되면 발생하는 이벤트 {@link SessionConnectEvent}를 처리합니다.
* <p> STOMP CONNECT 메시지 헤더에서 nickname을 추출해 웹소켓 세션 헤더에 저장합니다.
*/
@EventListener
public void handleSessionConnect(SessionConnectEvent event) {
SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor.wrap(event.getMessage());
String nickname = accessor.getFirstNativeHeader("nickname");

// 세션에 닉네임 저장
accessor.getSessionAttributes().put("nickname", nickname);

// 로깅을 위해 sessionId와 함께 보여줍니다
String sessionId = accessor.getSessionId();
log.info("sessionId: " + sessionId + ", nickname: " + nickname);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
public class MessageResponseDto {
private String content;
private String sessionId;
private String nickname;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
import com.example.spring_websocket.dto.response.MessageResponseDto;

public interface ChatService {
MessageResponseDto processMessage(MessageRequestDto requestDto, String sessionId);
MessageResponseDto processMessage(MessageRequestDto requestDto, String sessionId, String nickname);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

@Service
public class ChatServiceImpl implements ChatService {
public MessageResponseDto processMessage(MessageRequestDto requestDto, String sessionId) {
return new MessageResponseDto(requestDto.getContent(), sessionId);
public MessageResponseDto processMessage(MessageRequestDto requestDto, String sessionId, String nickname) {
return new MessageResponseDto(requestDto.getContent(), sessionId, nickname);
}
}

0 comments on commit 692bff8

Please sign in to comment.