개요

이전 포스팅에서 WebSocket을 활용해 back 과 front 를 연결하고,
메세지를 보냄으로써 연결이 잘 되었는지 확인 해 보았다.

이번 포스팅 에서는,
서로 다른 웹 브라우저에서 메세지를 보내고 받는 실시간 채팅 기능을 구현해 보고자 한다.


개발환경

작업 툴은 vscode를 사용하며,
웹 브라우저는 chrome과, Microsoft Edge로 진행한다.

UI

이전에 생성한 home.pug에서 간단한 UI 를 그려 확인 해 보자.

아직은 비어있지만 메세지를 받으면 리스트 형태로 받을 ul태그를 생성해준다.
그 아래 form태그를 부모 태그로 두고,
그 아래 텍스트를 입력할 수 있는 input태그와,
작성한 메세지를 보낼 수 있는 button태그를 생성한다.

데이터(텍스트) 전송

html 코드가 작성된 태그를 Client.js에서 가져온다.

const MessageList = document.querySelector('ul')
const MessageForm = document.querySelector('form')

event listener 를 MessageForm에 추가한다.

function handleSubmit(event){
    event.preventDefault()
    const input = MessageForm.querySelector('input')
    // console.log(input.value) // console 창에 input 영역에 입력한 텍스트를 출력
    socket.send(input.value) // front form 영역에서 서버로 데이터 전송
    input.value = "" // 빈 값을 정의하여 send button 을 클릭 시 내용을 비워줌
}

MessageForm.addEventListener('submit', handleSubmit)

다음과 같이 코드를 작성한 뒤,
console.log(input.value)의 주석을 풀면 브라우저 콘솔 창에 입력한 텍스트가 출력 되지만,
socket.send 명령어를 통해 입력한 텍스트를 Server.js에 보내준다.

input.value를 빈 문자열로 정의하여 텍스트를 입력 후 버튼을 클릭 시 input 영역을 비워줌.

에러

front 에서 보낸 데이터(텍스트)를 server 터미널에 출력할때,
다음과 같이 출력이 된다면 아래와 같은 형태로 재 랜더링 하여 다시 데이터를 보내주도록 하자.

console.log(message.toString('utf8'))

이는 맥 사용자 이외의 윈도우에서 해당하는 에러인듯하다..
(본인이 윈도우 사용자 )


Server.js의 터미널에 user 가 front 에서 입력한 텍스트가 잘 출력이 됨을 확인 했다.
이제 user 가 보낸 메세지를 다시 user 에게 보내줄 수 있도록 socket.send 함수를 사용한다.
즉,
front 영역에서 보낸 데이터를 server 를 거쳐 다시 front 에 띄워준다는 말이다.

socket.send(message)

이 때도 마찬가지로 콘솔 창에 다음과 같이 출력 된다면,
'utf8'옵션을 추가하여 다시 랜더링 해 주자.

1 번은 front 콘솔에 출력되는 메세지
2 번은 server 콘솔에 출력되는 메세지


다른 웹 브라우저 간의 통신

input영역 안에 텍스트를 입력 후 버튼을 클릭하면,
메세지를 전송하고 받는 기능을 구현 했다.

여기까지의 기능을 chrome 에서 테스트 했지만,
다른 웹 브라우저인 Microsoft Edge 에서 다시 테스트 해 보도록 하자.

역시나 chrome 에서 텍스트를 보내면 chrome 브라우저 에서만 받을 수 있고,
Edge 에서 보낸 텍스트는 Edge 브라우저 에서만 받을 수 있었다.

즉, 한 개의 서버가 서로 다른 브라우저로부터 데이터를 받고있고,
받은 데이터에 각각 답장(반환)을 해 주고 있다.


이번에는 한쪽의 브라우저에서 텍스트를 보내면,
다른 웹 브라우저에서도 데이터를 받을 수 있는 기능을 구현하려 한다.

해당 코드는 Chrome 과 Edge 두 브라우저에 연결 되었을때 실행되는 코드이다.

wss.on('connection', (socket) => {
    console.log('Connection to Browser 💌')
    socket.on('close', () => console.log('Disconnected to Browser ❌'))
    socket.on('message', (message) => {
        socket.send(message.toString('utf8'))
    })
})

해당 코드로 인해 두 브라우저 모두
서버가 연결되었다는 메세지와 함께 새로운 메세지를 받을 수 있다.
즉,
같은 코드로 두 개의 브라우저가 연결 되었다는 의미이다.

아니, 어쩌면 두 개 이상의 브라우저가 연결이 될지도 모른다.

그렇기에 먼저,
다수의 브라우저들을 데이터베이스로 받을 수 있게 빈 배열을 생성해준다.

// 두 개의 브라우저가 담겼다면,
const otherBrowser = [] // ex) [1, 2, ...]

빈 배열이 담긴 otherBrowser는,
누군가 서버에 연결을 시도한다면 그 connection 을 담는 역할을 한다.

// 브라우저들이 연결 되었을 때 `otherBrowser`에 넣어줌
otherBrowser.push(socket) 
---
// 메세지 영역의 함수
// 터미널에 "Buffer 68 65 6c 6c 6f 20 66 72 6f ..." 이 출력되어 utf-8 로 렌더링 해줌
otherBrowser.forEach((aSocket) => aSocket.send(message.toString('utf8')))

해당 코드로 인해 임의의 브라우저에서 받은 메세지를
socket 이 있는 모든 곳에 전달해 줄 수 있게 된 것이다.

Reference

https://nomadcoders.co/noom/lectures/3096