• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 리액트 웹소켓 useEffect 사용

리액트 웹소켓 useEffect 사용

6 글 보임 - 1 에서 6 까지 (총 6 중에서)
  • 글쓴이
  • #127247

    김수현
    참가자
    리액트로 웹소켓 사용해서 챗팅방 기능구현하고있습니다. send라는 버튼을 누르면  emitMessage 함수가 실행되어 웹소켓에 
    메세지가 보내지고 useeffect를 활용해 웹소켓에서 메세지를 받아와서 messages 라는 배열에 꽂는건데, 
    아래코드는 잘 작동합니다. 어떻게 작동되게는 했는데, 이해되지 안는점이 몇가지 있습니다. 
    
    
    useEffect(() => {
    socket.on("connect", () => {
    console.log("connected to server");
     });
    
    
    socket.on("message-broadcast", (data) => {
    setMessages((prevMessages) => [...prevMessages, data]);
     });
    return () => {
    socket.off("connect");
    socket.off("message-broadcast");
     };
     }, [socket]);
    
    => 1. socket이 []사이에 꽂혀져 있지 안은 빈배열이면, 컴포넌트 로딩시 작동은 한번만되야하는거아닌가요? 
    []사이 socket 이 없으면 
    
    socket.on("connect", () => {
    console.log("connected to server");
    });
    
    socket.on("message-broadcast", (data) => {
    setMessages((prevMessages) => [...prevMessages, data]);
    }); 이 두번실행되고 
    
    console.log("testing");는 한번만 잘 실행됩니다. 
    
    
    useEffect(() => {
    if (chatRoomId) {
    socket.emit("ask-join", chatRoomId);
     }
     }, [chatRoomId, socket]);
    
    => 2. 이부분도 왜 chatRoomId, socket 가 들어가있어야하는지 모르겠습니다. 이게 아니면  엄청많이 실행되서 두개 이상 엄청 많이 같은 메세지가 추가됩니다. 
    참고로 chatRoomId는 챗팅방 몽고디비에서 생성된 방 id입니다. 
    
    
    const emitMessage = () => {
    socket.emit("message-send", {
    chatUserId: `${LoggedinUser.id}`,
    chatUserName: `${LoggedinUser.userDisplayName}`,
    message: `${messageValue}`,
    room: `${chatRoomId}`,
     });
     };
    
    <button
    onClick={() => {
    sendMessage();
    emitMessage();
     }}
    >
     send
    </button> 
    
    
    
    #127272

    김수현
    참가자
    수정기능 못찾겠어서 그냥 여기 씁니다. .. 
    
    
    socket= io("http://localhost:3020");을 글로벌에 뒀더니 난리나서 useRef사용해서 
    사용방식 바꾸고 코드 변경했는데, 
    왜 페이지 시작하고 챗쓰면 실행이 안될까요, 그리고 messageSent라는 useState불리언 사용해서 메세지보내기 누를때마다 변경되게 해서 
    [messageSent]넣으면 , 두번째 클릭부터 됩니다. 그리고 메시지도 return문써서 쏘켓 off했는데도 2개씩 받아요 ... 왜그러죠 ? ㅜㅜ 
    
    
    const socketRef = useRef<Socket | null>(null);
    useEffect(() => {
    socketRef.current = io("http://localhost:3020");
    if (chatRoomId) {
    console.log("askingjoing");
    socketRef.current.emit("ask-join", chatRoomId);
    // console.log(socket);
     }
    if (socketRef.current) {
    console.log("실행전");
    socketRef.current.on("message-broadcast", (data) => {
    console.log("실행중", data);
    setMessages((prevMessages) => {
    return [...prevMessages, data];
     });
     });
    console.log("끝");
     }
    return () => {
    if (socketRef.current) {
    socketRef.current.off("connect");
    socketRef.current.off("ask-join");
    socketRef.current.off("message-broadcast");
     }
     };
     }, []);
    
    
    
    const emitMessage = () => {
    if (socketRef.current) {
    socketRef.current.emit("message-send", {
    chatUserId: `${LoggedinUser.id}`,
    chatUserName: `${LoggedinUser.userDisplayName}`,
    message: `${messageValue}`,
    room: `${chatRoomId}`,
     });
    return () => {
    if (socketRef.current) {
    socketRef.current.off("message-send");
     }
     };
     }
     };
    <button
    onClick={() => {
    sendMessage();
    emitMessage();
     }}
    >
     send
    </button>
    #127274

    김수현
    참가자
    서버사이드쪽 부분입니다 
    io.on("connection", (socket) => {
    socket.on("ask-join", (data) => {
    socket.join(data);
     });
    socket.emit("name", "kim");
    socket.on("message-send", (data) => {
    console.log("Message received on server:", data);
    io.to(data.room).emit("message-broadcast", {
    chatUserId: data.chatUserId,
    chatUserName: data.chatUserName,
    createdAt: data.createdAt,
    message: data.message,
    room: data.room,
    _id: data._id,
     });
     });
    }); // 연결확인
    #127283

    codingapple
    키 마스터
    strict mode 켜있으면 useEffect에 [] 넣어도 2번실행될 수 있습니다
    socket변수에 이미 뭐가 있으면 socket = io() 하지말라고 코드짜도 될듯요
    유저가 접속부터 잘 되는지 서버의 io.on("connection", (socket) => { 안에 console.log같은거부터 써봅시다
    #127325

    김수현
    참가자
    if (!socketRef.current) {
    socketRef.current = io("http://localhost:3020");
     } 로 수정하고, strict mode제거하고 , 유저접속확인했는데도 아직 중복됩니다. 
    서버connet속 콘솔들도 터미널에 두번씩 찍히는데 그럼 서버쪽 문제일까요?
    
    
    #127349

    codingapple
    키 마스터
    https://socket.io/how-to/use-with-react 처럼 다른파일에 socket 변수하나 만들어놓고 그거 사용해봅시다
    개발시에만 그렇고 npm run build해서 실행해보면 잘될수도 있습니다
    
    
6 글 보임 - 1 에서 6 까지 (총 6 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠