react 로 socket io 연결

정지훈·2022년 7월 8일
3

webSocket에 이전부터 관심이 있어서 찾아보았는데 webSocket은 크로스 브라우징이 안되는 곳이 있다고 해서 socket.io라이브러리로 만들어 보았다.

처음에 백엔드에서 설정을 해줘야 해서 폴더를 server와 client로 만들어 준 후
client에는 npx create-react-app . 을 한 후 react를 설치해준다.

그리고 server에 npm init을 하고 package.json을 만들어 준 후

npm i nodemon express socket.io cors

를 설치해 주고 index.js파일을 만든 후 작업을 시작해 준다.

const express = require("express");
const app = express();
app.use(cors());

server.listen(3001, () => {
  console.log("SERVER IS RUNNING");
});

express 서버를 3001로 만들어 준 후

const server = http.createServer(app);

const io = new Server(server, {
  cors: {
    origin: "http://localhost:3000",
    mathods: ["GET", "POST"],
  },
});

socket 서버를 설정해 준다.

그 후

io.on("connection", (socket) => {
  console.log(`User Connected: ${socket.id}`);
}); // 연결확인

socket에 connection 즉 연결을 해주면 client에서 웹에 접근을 하면 연결이 될 것이다.

하지만 백엔드에서만 이렇게 한다고 해서 연결이 되는게 아니라 프론트에서도 연결을 시켜줘야 한다.

client폴더로 가서

npm i socket.io-client

를 설치 해 주고

App.js 로 가서

import io from "socket.io-client";

const socket = io.connect("http://localhost:3001");

socket 서버에 연결을 해준다 (express에 설정된 url)

그 후

  const sendMessage = () => {
    socket.emit("send_message", { message: 'Hello' });
  };

이런식으로 버튼에다가 달아주고 클릭을 해주게 되면

이런 메시지가 나올것이다.

socket에서 이 메시지를 받으면 receive를 해줘야 한다. (응답을 해줘야 한다)

io.on("connection", (socket) => {
  console.log(`User Connected: ${socket.id}`);
  socket.on("send_message", (data) => {
    console.log(data);
    socket.broadcast.emit("receive_message", data); 
  });
}); 

이런식으로 다시 클라이언트로 보내면 된다. 그리고 다시 클라이언트로 돌아가서 받기 위해

  useEffect(() => {
    socket.on("receive_message", (data) => {
      setMessageRecived(data.message);
    });
  }, [socket]);

useEffect안에 socket이 반응할때마다 응답을 해주도록 하고 receive_message를 첫번째 인수에 넣고 하면 socket에서 오는 걸 받을 수 있다.

이렇게 실시간 적으로 주고 받을 수 있다.
하지만 broadcast로 하는거는 방이 존재하지 않고 모든 유저가 이용할 수 있다.
방이라는 개념을 넣기 위해서는

io.on("connection", (socket) => {
  console.log(`User Connected: ${socket.id}`);
  socket.on("join_room", (data) => {
    socket.join(data);
  });
  socket.on("send_message", (data) => {
    console.log(data);
    // socket.broadcast.emit("receive_message", data); // 1 대 다수
    socket.to(data.room).emit("receive_message", data); // 방 하나만
  });
}); // 연결확인

socket.to(room)을 이용하여 만약 room이 1번방이면 1번방에만 data를 응답해 줄 것이다.

  const [room, setRoom] = useState("");

  const JoinRoom = (e) => {
    if (room !== "") {
      socket.emit("join_room", room);
    }
  };
return (<div>    
        <input type="text" placeholder="Room Number,,," onChange={(e) => setRoom(e.target.value)} />
      <button onClick={JoinRoom}>Join Room</button>
</div>)

이렇게 input에다 방을 설정해주고 하면

방 54번만 메시지를 이용할 수 있고 55번으로는 54번에서 보낸 메시지가 안보일 것이다.

1개의 댓글

comment-user-thumbnail
2023년 10월 5일

안녕하세요! 프론트앤드 개발자 지망하는 학생입니다! socket.io 를 공부하다가 지훈님의 블로그 글을 보았는데요! 그룹채팅방을 만들고싶은데 많이 어렵더라구요..! 혹시 공부하는데에 있어서 질문같은 도움을 좀 받을 수 있을까요?

답글 달기