프로그래밍 공부방

[Socket.IO] Socket.IO 사용법 정리 본문

라이브러리

[Socket.IO] Socket.IO 사용법 정리

김갱갱 2023. 6. 6. 22:42

🐥 Socke.IO 사용법 정리

안녕하세요. 오늘은 socket.io 사용법에 대해서 알아보겠습니다.

채팅 기능을 구현하기 위해 socket.io를 사용했는데  나중에 socket을 사용할 일이 종종 있을 것 같아서 정리했습니다.


Socket.IO는 클라이언트와 서버 간의 짧은 대기 시간, 양방향 및 이벤트 기반 통신을 가능하게 하는 라이브러리

 

우선은 서버와 클라이언트로 나눠서 설명하겠습니다.


1. Server

1) 설치

일단 socket.io를 사용하기 위해 설치 먼저 진행해줍니다.

npm install socket.io

2) 서버 초기화

HTTP 서버를 이용한 Socket 서버 초기화

import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(httpServer, { /* options */ });

io.on("connection", (socket) => {
  // ...
});

httpServer.listen(3000);

HTTPS 서버를 이용한 Socket 서버 초기화

import { readFileSync } from "fs";
import { createServer } from "https";
import { Server } from "socket.io";

const httpsServer = createServer({
  key: readFileSync("/path/to/my/key.pem"),
  cert: readFileSync("/path/to/my/cert.pem") // 인증서 추가
});

const io = new Server(httpsServer, { /* options */ });

io.on("connection", (socket) => {
  // ...
});

httpsServer.listen(3000);

https 서버를 사용하기 위해서는 인증서를 추가해주는 작업을 해주어야 합니다.

 

👉 인증서를 추가해주는 방법

const httpsServer = createServer({
  key: readFileSync("/path/to/server-key.pem"),
  cert: readFileSync("/path/to/server-cert.pem"),
  requestCert: true,
  ca: [
    readFileSync("/path/to/client-cert.pem")
  ]
});

io.engine.on("connection", (rawSocket) => {
  rawSocket.peerCertificate = rawSocket.request.client.getPeerCertificate();
});

인증서를 추가해주기 위해서는 다음과 같은 코드를 추가로 작성을 해줘야합니다.

인증서는 SSL 인증서 발급 사이트를 이용하셔서 따로 발급한 후 적용시킬 수 있습니다.

만약에 AWS를 이용한 SSL 인증서 발급 방식이 궁금하시다면? 👉 AWS SSL 인증서 만들기

 

참고로 HTTP 서버를 이용해서 Socket 서버를 초기화하려고 한다면 나중에 배포시 문제가 생길 수 있습니다.

배포 후에는 프론트 서버가 http가 아닌 https가 되기 때문입니다. 따라서 로컬에서만 끝낼 것이 아니라면 https를 쓰는 것이 더 좋습니다.

 

CORS

const io = new Server(httpServer, {
  cors: {
    origin: "*",
    credentials: true
  }
});

CORS 처리 또한 추가해주세요.

origin에 요청을 허용할 사이트를 추가해줍니다. 만약 *을 넣어주면 모든 사이트를 허용한다는 의미입니다.

credentials는 인증 정보를 허용한다는 의미입니다. ex) 쿠키 ...

3) 연결

io.on("connection", (socket) => {
	...
});

4) 연결 해제

io.on("connection", (socket) => {
  socket.on("disconnect", (reason) => {
    // ...
  });
});

2. Client

1) 설치

일단 socket.io를 사용하기 위해 설치 먼저 진행해줍니다.

npm install socket.io-client

2) 클라이언트 초기화

const socket = io(); // front와 server가 같은 도메인일 경우
const socket = io("https://server-domain.com"); // 다른 도메인일 경우

다른 도메인일 경우에는 해당 서버의 url을 적어줍니다.

3) 연결

socket.on("connect", () => {
	console.log(socket.connected) // socket이 서버에 현결되어 있는지 여부: true or false
});

3) 연결 해제

socket.on("disconnect", () => {
	...
});

1. 그 외 이벤트

1) emit : 이벤트를 보낼 때 사용 | on : 이벤트를 받을 때 사용

👉서버에서는 hello라는 이름으로 이벤트 방출, 클라이언트에서는 hello라는 이름의 이벤트를 받을 수 있습니다.

// server
io.on("connection", (socket) => {
  socket.emit("hello", "world");
});

// client
socket.on("hello", (arg) => {
  console.log(arg); // world
});

👉위와는 반대로 클라이언트에서 이벤트 방출, 서버에서는 이벤트를 받고 있습니다.

// client
socket.emit("setRoomNum", router.query.id);

// server
socket.on('setRoomNum', (num: number) => {
  if (num) {
    socket.join(String(num));
    console.log(num, '방에 입장했습니다')
  }
})

이런 형태로 데이터를 주고 받는 것이 가능합니다.

socket.emit("deleteMessage", {
  roomNum: chatId,
  message: nexistMessage,
});

위와 같이 객체 형태의 데이터도 주고 받을 수 있습니다!

2) Room: 지정된 방에 소켓을 넣을 수 있습니다. (서버 전용 개념) 

socket.join("some room");
// ex) socket.join(String(num));

join을 이용해서 room에 접속할 수 있습니다. 저같은 경우에는 num값을 클라이언트로 받아와서 각각의 방을 만들 수 있게 만들어주는 방식을 이용했습니다.

io.to(msg.roomNum).emit('send Message', msg.message);

to를 이용해주면 해당 방에 연결되어 있는 모든 클라이언트들에게 메시지를 전달할 수 있습니다. (브로드캐스팅)

3) Namespace: 멀티플렉싱을 통해 분할이 가능하게 만듭니다.

io.of("/orders").on("connection", (socket) => {
  socket.on("order:list", () => {});
  socket.on("order:create", () => {});
});

io.of("/users").on("connection", (socket) => {
  socket.on("user:list", () => {});
});

of를 이용해서 분할이 가능합니다.

네임스페이스는 동적으로 생성하는 것 또 가능합니다.

const workspaces = io.of(/^\/\w+$/);

 

Namespace와 room의 개념이 헷갈릴 수 있는데 namespace가 좀 더 큰 개념이라고 생각하시면 됩니다.

namespace 안에 여러 개의 room들이 있는 겁니다.


🐥💬

socket을 사용할 때 약간 헷갈리는 부분들이 있었는데, 정리를 위해 공식문서를 더 자세하게 보니 좀 더 이해가 쉬워진 것 같습니다. 역시 헷갈릴 때는 공식 문서가 제일 좋은 것 같네요.