Socket.io - 실습 (room)

Namlulu·2021년 10월 31일
0

Socket

목록 보기
3/11

Room

각 소켓 (각각의 브라우저나 세션이 만드는 커넥션)은 Socket.io에서 제공하는 Room에 접속할 수 있다.

Sever

wsServer.on('connection', (socket) => {
  socket.onAny((event) => {
    console.log(`Socket Event: ${event}`);
  });

  // nickname
  // room
  socket.on('enter_room', (roomName, nickname, done) => {
    socket['nickname'] = nickname;
    socket.join(roomName);
    done();
    socket.to(roomName).emit('welcome', socket.nickname, countRoom(roomName));
    wsServer.sockets.emit('room_change', publicRooms());
  });

  socket.on('disconnecting', () => {
    socket.rooms.forEach((room) =>
      socket.to(room).emit('bye', socket.nickname, countRoom(room) - 1)
    );
  });

  socket.on('disconnect', () => {
    wsServer.sockets.emit('room_change', publicRooms());
  });

  socket.on('new_message', (msg, room, nickname, done) => {
    socket.to(room).emit('new_message', `${nickname}: ${msg}`);
    done();
  });
});

=> Nickname을 소켓에 저장한다. join 메서드를 통해 소켓에 해당 room을 저장하고, rooms에서 해당 소켓에 들어가있는 커넥션을 추적할 수 있다. 또한 to 메서드를 통해 해당 소켓에 있는 커낵션들에게 브로드캐스팅이 가능하다.

Client

const socket = io();

const welcome = document.getElementById('welcome');
const roomList = document.getElementById('roomList');
const form = welcome.querySelector('form');
const room = document.getElementById('room');

roomList.hidden = true;
room.hidden = true;

let roomName;
let nickname;

function showRoom() {
  welcome.hidden = true;
  roomList.hidden = false;
  room.hidden = false;
  changeTitleH3(roomName);
  changeUserH2(nickname);

  const msgForm = room.querySelector('#msg');
  msgForm.addEventListener('submit', handleMessageSubmit);
}

function changeTitleH3(user, newCount) {
  const h3 = room.querySelector('h3');
  console.log(newCount);
  h3.innerText = `Room ${user} ${newCount ? '(' + newCount + ')' : ''}`;
}

function changeUserH2(content) {
  const h2 = room.querySelector('h2');
  h2.innerText = `User ${content}`;
}

function handleRoomSubmit(event) {
  event.preventDefault();
  const roomElement = form.querySelector('#roomName');
  const nickElement = form.querySelector('#nickname');
  socket.emit('enter_room', roomElement.value, nickElement.value, showRoom);
  roomName = roomElement.value;
  nickname = nickElement.value;
  roomElement.value = '';
  nickElement.value = '';
}

form.addEventListener('submit', handleRoomSubmit);

function addMessage(message) {
  const ul = room.querySelector('ul');
  const li = document.createElement('li');
  li.innerText = message;
  ul.appendChild(li);
}

function handleMessageSubmit(event) {
  event.preventDefault();
  const input = room.querySelector('#msg input');
  const value = input.value;
  socket.emit('new_message', input.value, roomName, nickname, () => {
    addMessage(`You: ${value}`);
  });
  input.value = '';
}

socket.on('welcome', (user, newCount) => {
  changeTitleH3(roomName, newCount);
  addMessage(`${user} arrived!`);
});

socket.on('bye', (left, newCount) => {
  changeTitleH3(roomName, newCount);
  addMessage(`${left} left ㅠㅠ`);
});

socket.on('new_message', addMessage);

socket.on('room_change', (rooms) => {
  const ul = roomList.querySelector('ul');
  ul.innerHTML = '';

  if (rooms.length === 0) {
    return;
  }

  rooms.forEach((room) => {
    const li = document.createElement('li');
    li.innerText = room;
    ul.append(li);
  });
});

=> Room의 개수나 PublicRoom 파트는 뒷절 adapter에서 설명한다.

profile
Better then yesterday

0개의 댓글