Express + Socket.IO, 간단한 채팅 만들기

2020. 3. 8. 23:43BACKEND/Node

반응형

안녕하세요 〰️ 

오늘은 NodeJS + Express + Socket.io 를 사용해서 정말 - 간단한 단체 채팅방을 만들어보겠습니다.

일단 제가 보이는 부분을 많이 신경쓰다 보니,,,

요즘 유행한다는 'neumorphism'을 사용하여 채팅창을 제작해보았습니다. 

 

일단 결과창부터 볼까요?

 

 

오늘 만들어볼 채팅창입니다 〰️ 

 

일단 소켓이 뭔지 조금 알아볼까요? 아는 분들은 그냥 넘어가시면 됩니다 !

 

모든 소스는 깃허브에 올려두었으니 참고되셨으면 합니다^~^

 

 

Socket 통신 ?

HTTP통신은 클라이언트가 요청을 보내는 경우에만 서버가 응답하는 단방향 통신입니다.

Socket 통신은 Http 통신과 달리 서버와 클라이언트가 연결을 유지하며 실시간 양방향 통신으로 데이터를 주고 받는 방식입니다.

 

http 통신은 클라이언트가 요청을 보내면 서버가 응답을 하고 연결을 끊어버립니다.

반면, Socket 통신은 연결은 서버와 클라이언트의 지속적인 연결을 이어나갑니다. 

보통 특정 시간동안 통신을 하지 않으면 서버와 클라이언트의 연결을 끊습니다. 또, 연결을 지속적으로 하기 때문에 서버에서 요청을 먼저할 수 있다는 특징이 있습니다.

 

그럼 이러한 Socket 통신은 언제 사용이 될까요?

 

HTTP 통신은 거의 대부분의 통신에 해당합니다.

예를 들어, 어떤 블로그에 접속하기 위해 링크를 클릭하면 클라이언트는 주소를 옮겨달라는 요청을 하고, 서버는 그 요청을 받아 그에 해당하는 url로 응답을 줍니다. 이 때에는 단순히 데이터를 요청하고 응답하기만을 하는 단순한 요청을 하게 되죠.

 

Socket 통신은 HTTP 통신에 지속적인 연결성을 더합니다.

예를 들어 메신저를 통한 연락을 할 때, 채팅방에 들어서는 순간부터 "실시간"으로 메세지를 전달해야합니다. 

Socket 통신은 이러한 실시간 통신을 할 때 필요하게 됩니다.

 

 

 

 

CHATTING 만들기

자, 그럼 실제로 구현해볼까요?

* IDE는 VSCode를 사용하였습니다.

 

 

✔️  첫 번째, 프로젝트 생성

먼저, Express 프로젝트를 생성해봅시다. 

 

$ express { project_name }     // express 프로젝트 생성

 

명령어를 이용해서 프로젝트 하나를 만들어주세요!

( node, npm, express는 각자 설치해주세요! )

 

 

✔️  두 번째, 모듈 설치

socket.io 모듈을 설치해줍니다.

먼저, 터미널에서 프로젝트의 최상위 폴더로 이동해주세요!

 

$ cd { project_name }       // 터미널 명령어를 위해 프로젝트로 파일로 이동

 

혹은 프로젝트를 우클릭해서 open in Terminal을 하셔도 됩니다. 

 

$ npm install socket.io     // 프로젝트에 소켓 설치
$ npm install

 

을 순서대로 해줍니다.

package.json을 확인해보면 소켓이 잘 설치되어 있는 걸 확인할 수 있습니다.

 

 

✔️  세 번째, app.js

app.js에 socket을 붙여줍니다.

 

 

// socket 생성
app.io = require('socket.io')();

// or
const Server = require('socket.io');
const io = new Server();

socket.io를 가져와 app.io로 가져옵니다.

소켓을 생성하면서 옵션을 추가할 수도 있는데, socket document에서 더 자세히 확인해보세요❗️ 

 

 

하나씩 더 확인해볼게요!

 

app.io.on('connection',(socket) => { ... })

 

위의 코드는 connection 이라는 이벤트가 들어왔을 때, 그 다음 요소로 오는 콜백 함수를 호출합니다.

 

socket이라는 파라미터는 connection이 성공했을 때 connection에 대한 정보를 담고 있는 변수입니다.

이 socket을 사용해서 서버에서는 event listener를 만들면 됩니다!

 

socket.on('chat-msg-1', (msg) => {
    app.io.emit('chat-msg-2', msg);
  });

 

 

socket.on(eventName, callback)

  • eventName (String)
  • callback (Function)
  • Returns Socket

 

 

on( ... ) 메소드로 'chat-msg'라는 이벤트명을 설정해주고, 콜백함수를 지정합니다.

콜백함수 내의 emit( ... ) 메소드를 통해 같은 포트를 사용하고 있는 곳으로 msg라는 메세지를 출력합니다.

이벤트는 emit(‘event’)으로 전달하면 on(‘event’)으로 받습니다. 

 

socket.on('disconnect', () => {
      console.log('socket disconnect !');
  });

 

위의 코드는 socket 연결이 끊겼을 때 (disconnect 라는 이벤트가 들어왔을 때) 실행됩니다.

 

놀랍게도 소켓 통신을 거의 완성시켰습니다❗️ 

 

 

 

✔️  네 번째, .attach( )

이번엔 /bin/www 파일로 이동해 소켓과 서버를 연결시켜주겠습니다 〰️ 

 

 

위와 같이 코드를 입력하여 서버를 붙여줍니다!

socket을 사용하기 위한 모든 세팅이 끝났습니다 👏🏻👏🏻👏🏻

 

 

✔️  다섯 번째, 뷰 짜기

실제로 눈에 보여야 확인할 수 있기 때문에 출력을 위한 뷰를 짜봅시다.

 

 

html
  head
  style(type='text/css').
    * {
      background-color: #f5f5f5;
    }
    ul {
      height: calc(100% - 38%);
      overflow-y: scroll;
      margin-right: 40px;
    }
    li {
      list-style-type : none;
      padding: 10px;
      font-weight: 300;
      overflow: auto;
      text-overflow: ellipsis;
      white-space: break-spaces;
    }
    p {
      color: #296dc2;
      font-weight: 300;
      font-size: 30px;
      padding-top: 10px;
      text-align: center;
    }
    input {
      height: 50%;
      width: 60%;
      border-radius: 8px;
      margin: 0px 10px 20px 10px;
      box-shadow: inset 4px 4px 5px #eeeeee, inset -4px -4px 5px #ffffff !important;
      border: 2px #646a73;
      font-size: 14px;
    }

    button {
      margin: 0px 10px 20px 10px;
      border-radius: 15px;
      box-shadow: 8px 8px 15px #e9e9e9, -8px -8px 15px #ffffff;
      height: 50%;
      width: 20%;
      border: 0px;
      font-weight: 300;
      font-size: 16px;
    }
    .container {
      margin: 5% auto;
      position: relative;
      width: 100%;
      max-width: 70%;
      box-shadow: 8px 8px 15px #e9e9e9, -8px -8px 15px #ffffff;
      height: 80%;
      border-radius: 20px;
      padding: 5px 0px;
    }
    .inputContainer {
      bottom: 0px;
      border-radius: 20px;
      position: absolute;
      height: 15%;
      width: 100%;
      text-align: center;
    }

  body
    div.container
      p 💌 SOCKET CHAT 💌
      ul#messages
      div.inputContainer
        form
          input(id="msgInput" placeholder="      typing something !" type="text")
          button SEND



script(src="/socket.io/socket.io.js")
script(src="http://code.jquery.com/jquery-1.11.1.js")
script.
  $(() => {
    const name = prompt('이름을 입력해주세요');
    const socket = io();
  
    $('form').submit(() => {
      let msg = {name: name, messege:$('#msgInput').val()} 
      socket.emit('chat-msg-1', msg);
      $('#msgInput').val('');
      return false;
    });
  
    socket.on('chat-msg-2', (msg) => {
      $('#messages').append($('<li>').text(msg.name + '  :  ' +
      msg.messege));
    });
  });

view/index.jade 로 이동하여 기존의 코드를 모두 지우고 위의 코드를 복/붙해 넣어보세요!


코드를 잠깐 설명해보자면, 일단 위에는 jade템플릿에 맞춘 코드입니다.

script 내에는 jquery를 사용해서 코드가 실행되게끔 만듭니다.

 

const socket = io();

 

이 부분이 socket을 연결 해줍니다❗️

그 이후, index.jade 내의 form에서 button을 통해 submit을 하게 되면 

 

// index.jade -> submit의 콜백함수 내부
socket.emit('chat-msg-1', msg);

 

위 코드를 통해서 app.js에 있는

 

// app.js

socket.on('chat-msg-1', (msg) => {
    app.io.emit('chat-msg-2', msg);
  });

 

라는 코드가 실행됩니다.

그리고 그 내부의 app.io.emit('chat-msg')가 index.jade 내부에 있는 

 

// index.jade
socket.on('chat-msg-2', (msg) => {
      $('#messages').append($('<li>').text(msg.name + '  :  ' +
      msg.messege));
    });

 

을 실행하게 되어서 채팅창의 글자가 써지게끔 만들어주는 거죠.

 

 

✔️  여섯 번째, 프로젝트 실행

프로젝트 실행하기

자, 이제 프로젝트를 실행해서 확인해보겠습니다.

( 2번 순서에서 npm install을 하지 않으면 오류가 발생하니 꼭 해주세요 )

 

$ npm start

 

이 번엔 localhost:3000 으로 접근해서 잘 동작되는지 눈으로 확인해보겠습니다.

 

다음의 창에 이름(아이디)를 입력해주세요.

 

 

작동이 잘되네요❗️ 

다들 잘 확인하셨나요❓ 

굉장히 간단하게 채팅방을 제작해보았어요 ㅎㅎㅎㅎ

 

소스코드를 자유롭게 변경하면서 사용해보세요 〰️ 

반응형