🔔 #2.4 ~ 2.7
1. 방 만들기
>> server.js
join 메서드 하나로 쉽게 방을 만들 수 있음
rooms : 현재 소켓이 들어가있는 방을 표시
socket.id : 현재 소켓의 id 를 알 수 있는 메소드
# server.js
wsServer.on("connection", (socket) => {
# onAny = EventListener인셈, 이벤트가 발생하는지 확인할 수 있음
socket.onAny((event) => {
console.log(`Socket Event: ${event}`);
});
socket.on('enter_room', (roomName, done) => {
socket.join(roomName);
done();
socket.to(roomName).emit('welcome');
});
});
>> app.js
서버에서 enter_room 이벤트를 받겠다고 했으니 클라이언트에서는 enter_room 이벤트를 전송해줘야한다
handleRoomSubmit 를 조금 수정해준다
원래 있었던 backendDone 함수를 showRoom으로 바꿔주고, 안에 있는 backendDone도 바꿔준다.
추가로 굳이 payload를 객체 형태로 전달할 필요가 없어서 input.value를 따로 밖으로 빼버림
const socket = io();
const welcome = document.getElementById('welcome');
const form = welcome.querySelector('form');
const room = document.getElementById('room');
room.hidden = true; # 방에 들어가기 전 닉네임이나 메세지를 보낼 수 있는 form 박스가 보지이 않도록 함
let roomName;
# html의 ul 요소에 li 요소를 생성해서 자식 요소로 채팅 내용을 추가해 화면에 나타내는 함수
function addMessage(message){
const ul = room.querySelector('ul');
const li = document.createElement('li'); # li 태그 생성
li.innerText = message;
ul.appendChild(li);
}
function showRoom() {
welcome.hidden = true;
room.hidden = false; # hidden 기능 끄기
const h3 = room.querySelector('h3');
h3.innerText = `Room ${roomName}`;
}
function handleRoomSubmit(event) {
event.preventDefault();
const input = form.querySelector("input");
socket.emit("enter_room", input.value, showRoom);
roomName = input.value; # roomName에 입력한 방 이름 저장
input.value = "";
}
form.addEventListener('submit', handleRoomSubmit);
2. 알림 보내기
사용자가 접속했을 때와 접속이 끊어졌을 때 알림을 보내는 기능 추가
to / emit 을 이용해 roomName 이라는 방에 있는 사람들에게 welcome 메세지를 보낼 수 있었는데, \
disconnecting 이벤트 : 클라이언트가 서버와 연결이 끊어지려고 할 때, 아직 채팅방을 나가기 전인 상태에서 실행되는 이벤트
>> server.js
disconnecting 이라는 상태를 통해 클라이언트가 서버와 연결이 끊어졌을 때 해당 클라이언트가 소속해있던 방에 bye 라는 메세지를 남길 수 있음
# server.js
wsServer.on("connection", (socket) => {
socket.onAny((event) => {
console.log(`Socket Event: ${event}`);
});
socket.on('enter_room', (roomName, done) => {
socket.join(roomName);
done();
socket.to(roomName).emit('welcome');
});
socket.on('disconnecting', () => {
socket.rooms.forEach((room) => socket.to(room).emit('bye'));
});
});
>> app.js
bye 이벤트 발생시 addMessage 함수를 통해 "Someone left ㅠㅠ" 라는 메세지가 화면에 출력되게 한다
socket.on("welcome", () => {
addMessage("Someone joined!");
});
socket.on("bye", () => {
addMessage("Someone left ㅠㅠ");
});
3. 메세지 보내기
>> app.js
handleMessageSubmit 에서 value 를 굳이 따로 만든 이유는 만들지 않았을 때 생기는 문제에 대해 생각해보면 됨
value 값을 따로 저장해 두지 않았을 때 addMessage 안에 들어있는 value 가 원래 input.value 인데,
== > addMessage(`You: ${input.value}`);
만약 input.value를 따로 저장해주지 않으면 socket.emit 함수가 동작하고 메세지 보내기 전에 input.value 를 초기화 하는 작업이
비동기로 먼저 작동해서 addMessage 가 돌아갈 때는 이미 우리가 보내고 싶었던 input.value 가 초기화 됨
이를 방지하기 위해 값을 따로 저장함
function handleMessageSubmit(event){
event.preventDefault();
const input = room.querySelector("input");
const value = input.value;
socket.emit('new_message', input.value, roomName, () => {
addMessage(`You: ${value}`);
}); # 백엔드로 new_message 이벤트 날림
input.value = '';
}
서버로부터 메세지를 전송받았을 때 이벤트로 처리해준다.
addMessage 에는 별도 매개변수를 넣지 않아도 msg 가 잘들어감
socket.on("new_message", addMessage);
# socket.on("new_message", (msg) => {addMessage(msg)});
4. 닉네임
닉네임을 설정하고, 메세지를 보냈을 때 누가 보낸 메세지인지 확인 할 수 있도록 해볼까여
>> home.pug
name 과 msg id 를 가진 form 2개 생성
div#room
h3
ul
form#name
input(placeholder='nickname', required, type='text')
button save
form#msg
input(placeholder='message', required, type='text')
button Send
>> app.js
querySelector를 통해 id가 room인 요소 아래에 있는 것들 중에서
name이나 msg라는 id를 가진 input을 찾아 input으로 등록하게 되는 구조
function handleMessageSubmit(event){
event.preventDefault();
const input = room.querySelector("#msg input");
const value = input.value;
socket.emit('new_message', input.value, roomName, () =>{
addMessage(`You: ${value}`);
});
input.value = '';
}
function handleNicknameSubmit(event){
event.preventDefault();
const input = room.querySelector("#name input");
socket.emit('nickname', input.value);
}
function showRoom() {
welcome.hidden = true;
room.hidden = false;
const h3 = room.querySelector('h3');
h3.innerText = `Room ${roomName}`;
const msgForm = room.querySelector("#msg");
const nameForm = room.querySelector("#name");
msgForm.addEventListener("submit", handleMessageSubmit);
nameForm.addEventListener("submit", handleNicknameSubmit);
}
socket.on("welcome", (user) => {
addMessage(`${user} arrived!`);
});
socket.on("bye", (left) => {
addMessage(`${left} left ㅠㅠ`);
});
>> server.js
새로운 메세지와 어느 방인지 , 처리가 다 끝나면 어떤 함수를 실행할지 받아서 작업하고, 닉네임과 메세지가 뜨도록 설정
done 함수는 백엔드가 아닌 프론트로 돌아가서 작동됨
wsServer.on("connection", (socket) => {
socket['nickname'] = 'Anon'; # 기본 닉네임을 만들기 위해 처음엔 익명 이라는 이름을 디폴트로 설정
socket.onAny((event) => {
console.log(`Socket Event: ${event}`);
});
socket.on('enter_room', (roomName, done) => {
socket.join(roomName);
done();
socket.to(roomName).emit('welcome', socket.nickname);
});
socket.on('disconnecting', () => {
socket.rooms.forEach((room) => socket.to(room).emit('bye', socket.nickname));
});
socket.on('new_message', (msg,room, done) => {
socket.to(room).emit('new_message', `${socket.nickname}: ${msg}`);
done();
});
socket.on('nickname', nickname => socket['nickname'] = nickname);
});
'FrameWork > Express.js' 카테고리의 다른 글
5 . 노마드코더 zoom 클론 - 방이름띄우기/방 사람수/admin panel (0) | 2023.02.05 |
---|---|
3 . 노마드코더 zoom 클론 - socket IO (0) | 2023.01.15 |
2 . 노마드코드 zoom클론코딩 - 채팅기능 구현하기 (0) | 2023.01.15 |
1 . 노마드코드 zoom클론코딩 - 환경설정/webSocket으로 클라이언트-서버 연결 (0) | 2023.01.15 |