Socket.io를 활용한 Chat 1탄

펭도리·2021년 3월 20일
0

Project

목록 보기
4/5
post-thumbnail

socket.io에 대한 간단한 지식을 여기에 정리해놓았다.

오늘은 socket.io를 활용해 chat을 만들어보았다.

코딩을 하면서 어느쪽이 User Browser이고 어느쪽이 Server인지 계속해서 혼동이 왔다.
나중에는 나만의?? 시점으로 생각하여 작업을 마무리하였다.
처음으로 양방향통신을 접하면서 어렵게 느꼇던 것은 평상시 express server와 js파일은 각각 1대1 통신이라고 생각하고 만들었지만 이번 채팅서비스는 여러사람이 한번에 이용한다는 점이 조금 어색하게 다가왔던 것이였다.

이를 해결하기위한 방법을 알아보던중 socket.ioUser Browser에 각각의 socket.id가 할당된다는 것을 알게되었다.

우선 저번 시간에 다루지 않았던 노드의 기본 모듈중 네트워크를 다루는 http 모듈에 대해 알아보도록 하자

const express = require('express');
const server = express();
const http = require('http').createServer(server);

express 모듈을 express라는 이름에 저장해주고 server이라는 변수에 express객체를 담아준다.
http모듈을 createServerexpress객체를 받아서 서버를 생성한다.

즉,
Express를 사용하여 Http 서버를 생성한다. 그리고 생성된 Http 서버를 socket.io serverupgrade한다.

위 과정의 내용
const io = require('socket.io')(http);

이제 채팅을 할 세팅이 끝났다. 이제 채팅을 시작해보자.

일단 socket.io의 이벤트는 emit으로 시작하여 on으로 받는다.

예제를 보자

user 측

const socket = io();

DOM.chat.addEventListener('submit', function(e) {
    if(name.value !== '' && name.value !== null && message.value !== '') {
        socket.emit('send message', name.value, message.value, socket.id);
        message.value = '';
        e.preventDefault();
    }
});

server 측

socket.on('send message', function(name, text, socketId) {
    let msg = name + "<br>" + text;
    socket.name = name;
    io.emit('receive message', msg, socketId);
});

user 측

socket.on('receive message', function(msg, socketId) {
    const speech_bubble = _.$create('div');
    _.addClass(speech_bubble, 'speech_bubble');
    const text = _.$create('div');
    _.addClass(text, 'bubble');
    _.addHTML(text,msg);
    _.append(speech_bubble, text);
    _.append(chatLog, speech_bubble);

    if(socket.id === socketId) {
        _.addClass(text, float_right);
    }
    // 새로운 채팅 추가시 자동으로 스크롤 다운. // scrollTop = 현재 스크롤값  scrollHeight = 변한 값
    chatLog.scrollTop = chatLog.scrollHeight;
});

위 부분을 설명하기 앞서 동작을 눈으로 보고 확인해보자.

이렇게 우리가 전송하고자 하는 내용을 입력후 전송을 하게되면 socket.emit을 통해 send message이벤트를 발생시켜 메세지가 서버측으로 전달되고 서버측에서는 socket.on로 전달 인자를 받아 그 문자를 재조합하여 io.emit을 통해 recive message 이벤트를 발생시켜 현재 채팅을 사용하고 있는 모든 유저들의 브라우저에 메세지를 뿌려준다.

여기서 처음으로 겪었던 문제점이 있었다.

카카오톡과 같은 채팅 또는 다른 채팅어플들을 보더라도 채팅을 작성하는 입장에서 보내는 메세지는 우측에 나열되는 것이였다. 이것을 어떻게 할 수 있을까? 라고 생각하고 찾아보니 다음과 같은 내용을 알 수 있었다.

const socket = io();

이 브라우저에 접속하는 모든 유저들은 자신만의 socket.id를 가지게된다. 이거를 if문으로 비교하여 이 메세지를 보낸것이 나인지 아니면 다른 유저인지 비교하여 우측정렬 좌측정렬의 기준을 잡아주면 되었다.

다음 코드가 이 경우의 예이다.

if(socket.id === socketId) {
    _.addClass(text, float_right);
}

여기서 socket.id현재 브라우저를 열고있는 유저만의 고유한 ID 이다. 그리고 socketIdsend message 이벤트를 발생시킬때 인자로 같이 넘겨준 socket.id이다. 이 아이디를 서버측에서 receive message를 발생시킬때 같이 넘겨주어 두개의 아이디가 같을경우는 메세지를 보낸 본인이 되고 다를 경우 메세지를 받는 유저의 입장인 것이다.

1탄 마무리... 나머지는 2탄에서~~

profile
풀스택 개발자가 되고싶은 코린이 이한글

2개의 댓글

comment-user-thumbnail
2021년 3월 20일

틀린점이 있다면 댓글로 적어주세요 ㅎㅎ 바로바로 반영하여 수정하겠습니다.

답글 달기
comment-user-thumbnail
2021년 3월 21일

emit 에서 보낸걸 on 에서 받고, 그걸 다시 emit으로 보내는 식으로 통신이 가능한 거군요. ㅎㅎㅎ 배워갑니다~~

답글 달기