개념
node.js에서는 많은 웹 소켓 구현체가 있다. 대표적으로 socket.io와 ws가 있다. 지금 여기서 내가 사용할 기술은 socket.io이다.
웹에서 데이터를 주고 받을 땐 HTTP를 사용한다. 하지만 HTTP는 요청이 있어야만 응답을 보내주기 때문에 실시간을 보장하지 않는다. HTML5 WebSocket은 매우 유용한 기술이지만 오래된 브라우저의 경우 지원하지 않는 경우가 있다.
브라우저 간 호환이나 이전 버전 호환을 고려하여 Node.js를 위한 강력한 Cross-platform WebSocket API인 Socket.io를 사용하는 것이 바람직하다.
socket.io를 통한 양방향 통신 구현하기
1) 백엔드에서 socket.io 설치하기(서버)
npm i socket.io
1-1) 서버측 코드 작성하기
var app = require('express')();
var server = require('http').createServer(app);
// http server를 socket.io server로 upgrade한다
var io = require('socket.io')(server);
server.listen(3000, function() {
console.log('Socket IO server listening on port 3000');
});
Express를 사용하여 Http 서버를 생성한다. 그리고 생성된 Http 서버를 socket.io server로 upgrade한다.
1-2) Socket IO 이벤트 통신
// 해당 이벤트를 받고 콜백함수를 실행
socket.on('받을 이벤트 명', function(msg) => {
})
소켓IO 의 메소드의 특징은 클라이언트에서 발생하는 이벤트는 개발자가 임의로 설정할 수 있다.이벤트는 문자열로 지정하며 직접 이벤트를 발생시킬 수 있다.
connection 이벤트 핸들러 작성하기
// connection이 수립되면 event handler function의 인자로 socket이 들어온다
io.on('connection', function(socket) {
});
- 클라이언트가 socket.io 서버에 접속했을 때 connection 이벤트가 발생한다. connection event handler를 정의한다. connection event가 발생하면(즉 클라이언트가 접속하면) 클라이언트가 전송한 메시지를 수신하거나 클라이언트에게 메시지를 송신한다.
- socket 객체 : connection event handler function의 인자로 socket 객체가 전달된다. 개별 클라이언트와의 interacting을 위한 기본적인 객체이다.
- io 객체 : 연결된 전체 클라이언트와의 interacting을 위한 객체이다.
1-3) Socket IO 송수신 메소드
클라이언트가 전송한 메시지 수신
✅ 현재 접속되어 있는 클라이언트로부터의 메시지를 수신하기 위해서는 on 메소드를 사용한다.
- 이벤트명 : 클라이언트가 메시지 송신 시 지정한 이벤트 명(string)
- function : 이벤트 핸들러이다. 핸들러 함수의 인자로 클라이언트가 송신한 메시지가 전달된다.
socket.on('event_name', function(data) {
console.log('Message from Client: ' + data);
});
클라이언트에게 메시지 송신
- io.emit : 접속된 모든 클라이언트에게 메시지를 전송한다.
- io.to(id).emit : 특정 클라이언트에게만 메시지를 전송한다. id는 socket 객체의 id 속성값이다.
- socket.emit : 메시지를 전송한 클라이언트에게만 메시지를 전송한다.
- socket.broadcast.emit : 메시지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메시지를 전송한다.
// 접속된 모든 클라이언트에게 메시지를 전송한다
io.emit('event_name', msg);
// 메시지를 전송한 클라이언트에게만 메시지를 전송한다
socket.emit('event_name', msg);
// 메시지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메시지를 전송한다
socket.broadcast.emit('event_name', msg);
// 특정 클라이언트에게만 메시지를 전송한다
io.to(id).emit('event_name', data);
2) 프론트에서 socket.io 설치하기(Client)
npm i socket.io-client
2-1) socket.io에 접속하기
import {io} from "socket.io-client";
const socket = io("<http://localhost:5001>");
export default socket;
Namespace
socket.io는 서로 다른 엔드포인트(endpoint) 또는 경로(path)를 할당하는 의미로 socket에 namespace를 지정할 수 있다.
namespace를 특별히 지정하지 않은 경우 default namespace인 /를 사용하게 된다.
// 지정 namespace로 접속한다
var socket = io('/my-namespace');
Room
각 namespace 내에서 임의의 채널을 지정할 수 있다. 이를 room이라 하며 이를 통해 room에 join되어 있는 클라이언트 만의 데이터 송수신이 가능하게 된다.
즉 각 클라이언트는 socket을 가지게 되며, 각각 namespace를 가지고, namespace는 room을 가질 수 있다.
socket은 유니크한 socket.id로 구별된다. socket.io는 각 socket은 room의 식별자로 socket.id를 사용하여, 자동으로 room을 생성하고 join시킨다.
room에 join하기 위해서는 join 메소드를 사용한다.
👇🏻 참고
https://velog.io/@uoayop/Node.js-Socket.io-채팅방-구현해보기-1