TIL

24/01/18 TIL __ 웹소켓

GABOJOK 2024. 1. 18. 23:58

 

실시간 스트리밍 서비스를 최종 프로젝트로 계획하고 진행중이라 웹소켓을 공부했다. 

아프리카 티비 같은 서비스에 보면 옆에 실시간 채팅이 있는데 그 부분을 구현하려고 진행하게 되었다. 

 

실제 프로젝트는 nest.js로 했지만, 일단 이해를 먼저 하기 위해서 express로 진행을 하게되었다. 

 

 

🌵 웹소켓   web socket

실시간 채팅을 위해 많이 사용하는 도구인데, 실시간 양방향 통신을 제공하는 프로토콜 중 하나이다.

(프로토콜 : 컴퓨터나 장치간에 통신하기 위한 규칙)

http 프로토콜과 비교해 보니 이해가 쉬웠는데,

  http web socket
통신과정  req를 보내야 서버가  res를 응답줄 수 있는 수동적 관계 클라이언트에서 서버로 요청이 온것을
처리한 이후에도 연결 유지.
(마냥 기다리지 않음)
서버가 유저를 기억하는가
(stateLess / stateFul)
좀전에 본 유저 기억 못한다 연결을 닫거나 명시적 종료 전까지는 기억한다. 
예시 탁구 와이파이

 

 

이런 특성이 있다. 

지금까지 만지던 통신과는 달라 흥미로웟다. 

 

 

 

 

🌵 WS

node.js 에서 웹소켓 실행을 돕는 도구인데,

웹소켓의 중심부. 중심기능만 있는 패키지 이다. 

이것을 활용해 실시간 채팅기능을 만들 수 있지만, 문자열만 전송이 가능하고, 

socket io에 있는 다른 편리한 기능들은 없다.

 

 

 

🌵 Socket IO

만약 실시간 채팅 기능을 ws를 통해 만들었는데, 어떤 유저 브라우저에서는 지원되지 않아서 작동하지 않는다면,

이는 꽤 이슈일 것이다. 이런 부분들은 socket io를 사용하게 되면 해결이 된다.

모든 브라우저, 모든 기기, 모든 플랫폼에서 동일하게 웹소켓 기능 작동이 가능하도록 지원하기 때문이다. 

뿐만 아니라, 잠시 연결이 끊겨도 계속해서 재연결을 시도하고,

room을 직접 만들어 관리하지 않아도 되며, socket id 또한 제공한다. 

거기에 string타입만 보내는 게 아닌 다양한 타입을 지원하기 때문에 훨씬 편리하다. 

 

생각해 보면 socket io를 선택하지 않을 이유는 딱히 없다. 

안정성, 탄력성 등등 을 생각해 봤을때 좋은 선택지라고 보여지기 때문이다. 

 

내가 이해한 socket IO의 플로우는 이렇다. 

a유저가 채팅방에 메세지를 보내면, 프론트에서 클릭이벤트가 구동되고,

해당 이벤트가 호출되어 백엔드로 넘어간다. 

백엔드에서 해당 이벤트가 호출되며, 그곳에서 어떤 유저들에게 해당 메시지를 보낼건지 설정 후 다시 프론트로 보내준다. 

그럼 프론트는 이것을 받아서 페인팅 해 유저에게 보여준다. 

 

 

아래는 해당 로직에 대한 부분이다.

// 프론트 코드 _ app.js

msgForm.addEventListener('submit', handleNickNameSubmit);
  
 //메세지 이벤트
function handleMessageSubmit(event) {
  event.preventDefault();
  const input = room.querySelector('#msg input');
  const value = input.value;
  socket.emit('new_message', input.value, roomName, () => {
    //이 콜백함수는 백에서 done()을 호출해야 실행됨. //이 마지막 함수는 백엔드에서 실행시킬 수 있다.
    addMessage(`You: ${value}`); 
  });
  input.value = '';
}

 

// 백엔드 코드 __ server.js

//프론트에 있는 new_message이벤트 실행시키기 done()을 호출하면, 프론트에서 그 이후 코드를 실행하는 구조
socket.on('new_message', (msg, room, done) => {
  socket.to(room).emit('new_message', `${socket.nickname}: ${msg}`);
  done();
});

 

 

// 프론트 코드 __ app.js

//백엔드 에서 받은 데이터로 그려주기
socket.on('new_message', (msg, countRoom) => {
  const h3 = room.querySelector('h3');
  h3.innerText = `Room ${roomName}, 인원: ${countRoom}`;
  addMessage(msg);
});

//메세지 그려주는 함수
function addMessage(message) {
  console.log(message);
  const ul = room.querySelector('ul');
  const li = document.createElement('li');
  li.innerText = message;
  ul.appendChild(li);
}

 

 

 

 

참고

https://socket.io/

 

Socket.IO

Reliable Rest assured! In case the WebSocket connection is not possible, it will fall back to HTTP long-polling. And if the connection is lost, the client will automatically try to reconnect.

socket.io