You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importiofrom'socket.io-client';// Socket 연결constsocket=io('ws://localhost:3001/chat',{auth: {token: localStorage.getItem('accessToken')// JWT 토큰}});// 연결 성공 확인socket.on('connected',(data)=>{console.log('✅ 서버 연결 성공:',data);// { message: "채팅 서버에 성공적으로 연결되었습니다.", userId: 1, nickname: "사용자1", connectedAt: "2024-01-01T..." }});// 연결 에러 처리socket.on('connect_error',(error)=>{console.error('❌ 연결 실패:',error.message);// 토큰 만료시 재로그인 처리});
// 채팅방 참가constjoinChatRoom=(chatRoomId)=>{socket.emit('join_room',{ chatRoomId });};// 참가 성공 응답socket.on('joined_room',(data)=>{console.log(`채팅방 ${data.chatRoomId} 참가 완료`);setCurrentChatRoom(data.chatRoomId);});// 다른 사용자 참가 알림socket.on('user_joined',(data)=>{console.log(`${data.nickname}님이 참가했습니다.`);showNotification(data.message);});
lettypingTimer;// 타이핑 시작consthandleTypingStart=(chatRoomId)=>{socket.emit('typing:start',{ chatRoomId });// 3초 후 자동으로 타이핑 중단clearTimeout(typingTimer);typingTimer=setTimeout(()=>{socket.emit('typing:stop',{ chatRoomId });},3000);};// 타이핑 중단consthandleTypingStop=(chatRoomId)=>{clearTimeout(typingTimer);socket.emit('typing:stop',{ chatRoomId });};// 다른 사용자 타이핑 상태 수신socket.on('typing:status',(data)=>{if(data.isTyping){showTypingIndicator(`${data.nickname}님이 입력 중...`);}else{hideTypingIndicator(data.userId);}});
importReact,{useState,useEffect,useRef}from'react';importiofrom'socket.io-client';constChatRoom=({ chatRoomId, accessToken })=>{const[socket,setSocket]=useState(null);const[messages,setMessages]=useState([]);const[inputMessage,setInputMessage]=useState('');const[typingUsers,setTypingUsers]=useState([]);constmessagesEndRef=useRef(null);useEffect(()=>{// Socket 연결constnewSocket=io('ws://localhost:3001/chat',{auth: {token: accessToken}});newSocket.on('connected',(data)=>{console.log('연결 완료:',data);// 채팅방 참가newSocket.emit('join_room',{ chatRoomId });});// 메시지 수신newSocket.on('message:receive',(message)=>{setMessages(prev=>[...prev,message]);scrollToBottom();});// 멘션 알림newSocket.on('mention:receive',(mention)=>{// 현재 사용자가 멘션된 경우에만 알림if(mention.mentionedUserId===getCurrentUserId()){showNotification(`${mention.senderNickname}님이 회원님을 멘션했습니다.`);}});// 타이핑 상태newSocket.on('typing:status',(data)=>{setTypingUsers(prev=>{if(data.isTyping){return[...prev.filter(u=>u.userId!==data.userId),data];}else{returnprev.filter(u=>u.userId!==data.userId);}});});setSocket(newSocket);return()=>{newSocket.disconnect();};},[chatRoomId,accessToken]);constsendMessage=()=>{if(inputMessage.trim()&&socket){// @멘션 파싱 (간단한 예시)constmentionRegex=/@(\w+)/g;constmentions=[];letmatch;while((match=mentionRegex.exec(inputMessage))!==null){// 실제로는 사용자 닉네임을 ID로 변환하는 로직 필요constuserId=getUserIdByNickname(match[1]);if(userId)mentions.push(userId);}socket.emit('message:send',{
chatRoomId,type: 'text',content: inputMessage,mentionUserIds: mentions});setInputMessage('');}};consthandleInputChange=(e)=>{setInputMessage(e.target.value);// 타이핑 상태 전송if(socket){socket.emit('typing:start',{ chatRoomId });}};constscrollToBottom=()=>{messagesEndRef.current?.scrollIntoView({behavior: 'smooth'});};return(<divclassName="chat-room"><divclassName="messages">{messages.map((message)=>(<divkey={message.id}className="message"><strong>{message.sender.nickname}: </strong>{message.content}<small>{newDate(message.createdAt).toLocaleTimeString()}</small></div>))}{typingUsers.length>0&&(<divclassName="typing-indicator">{typingUsers.map(u=>u.nickname).join(', ')}님이 입력 중...
</div>)}<divref={messagesEndRef}/></div><divclassName="input-area"><inputtype="text"value={inputMessage}onChange={handleInputChange}onKeyPress={(e)=>e.key==='Enter'&&sendMessage()}placeholder="메시지를 입력하세요... (@닉네임으로 멘션)"/><buttononClick={sendMessage}>전송</button></div></div>);};exportdefaultChatRoom;
그룹 채팅 특별 고려사항
1. 멤버 관리
// 그룹 채팅방에서는 여러 명이 동시에 메시지를 보낼 수 있음// 메시지 순서 보장을 위해 서버에서 timestamp 사용// 새 멤버 참가시socket.on('user_joined',(data)=>{// 그룹 채팅방 멤버 목록 업데이트updateChatRoomMembers(data.userId,'add');showSystemMessage(`${data.nickname}님이 참가했습니다.`);});
2. 멘션 기능
// 그룹 채팅에서 @all, @here 같은 특별 멘션도 지원 가능constsendGroupMessage=(content)=>{letmentionUserIds=[];if(content.includes('@all')){// 모든 멤버 멘션mentionUserIds=getAllChatRoomMemberIds();}else{// 개별 멘션 파싱mentionUserIds=parseMentions(content);}socket.emit('message:send',{
chatRoomId,type: 'text',
content,
mentionUserIds
});};