본문 바로가기
개발/Node.js

[Node.js] socket.io로 채팅 서버 만들기 1 - 웹 소켓 연결

by 윤호 2021. 1. 25.

익스프레스로 채팅 서버를 만들어보겠습니다. socket.io 모듈을 사용해서 빠르게 구현할 수 있습니다.

목차

  • 웹 소켓이란
  • 채팅서버 작동 방식
  • 서버에서 socket.io 연결
  • 클라이언트에서 socket.io 연결

웹 소켓이란

웹소켓은 HTML5 표준 기술로, 사용자의 브라우저와 서버 사이의 동적인 양방향 연결 채널을 구성합니다. 그러나 웹소켓은 HTML5의 기술이기 때문에 오래된 버전의 웹 브라우저는 웹소켓을 지원하지 않습니다. Socket.io는 자바스크립트를 이용하여 브라우저 종류에 상관없이 실시간 웹을 구현할 수 있도록 한 기술입니다.

채팅서버 작동방식

 

socket.io를 사용한 채팅서버의 작동

socket.io는 서버와 클라이언트 양쪽에서 모두 따로 사용하며 서버용 socket.io와 클라이언트용 socket.io는 서로 다릅니다. 채팅 메시지를 주고받는 과정을 간단히 말하면 이벤트로 클라이언트 socket.io가 서버 socket.io에 메시지를 보내고, 메시지를 받은 서버는 적절한 클라이언트에게 받은 메시지를 보냅니다.

서버에서 socket.io 연결

익스프레스 서버를 생성하고 서버와 클라이언트에 socket.io를 연결해 보겠습니다.

 

% npm install socket.io 명령어로 socket.io 모듈을 설치합니다. 이외에 static 모듈을 설치합니다.

 

서버 파일 app.js는 다음과 같습니다.

// npm install express
// npm install static
var express = require('express')
    , http = require('http')
    , path = require('path');

var static = require('serve-static');

var app = express();
app.set('port', process.env.PORT || 3000);
app.use('/public', static(path.join(__dirname, 'public')));

//==== 서버 실행 ====//
const httpServer = http.createServer(app).listen(app.get('port'), function(){
    console.log('서버가 시작되었습니다. 포트 : ', app.get('port'));
});

//==== socket.io ====//
const io = require("socket.io")(httpServer);
console.log('socket.io 요청을 받아들일 준비가 되었습니다.');

// 클라이언트가 연결했을 때의 이벤트 처리
io.on("connection", (socket) => {
    console.log('connection info : ', socket.request.connection._peername);
});

서버 객체를 인자로 받아 서버에서 사용할 socket.io 객체를 생성합니다. on 메소드로 connection 이벤트를 정의합니다. connection 이벤트는 client socket.io와 연결 되었을 때 발생합니다. 콜솔로 찍는 connection info는 연결된 client 소켓의 주소와 포트넘버 정보입니다.

클라이언트에서 socket.io 연결

클라이언트에서 socket.io를 사용하기 위해 참조할 socket.io.js 파일이 필요합니다. 이는 socket.io 모듈을 설치 했다면 node_modules/socket.io-client/dist 경로에 있습니다. 혹은 socket.io-client 깃허브에서도 다운받을 수 있습니다.  마찬가지로 dist 디렉토리에 파일이 있습니다. socket.io 디렉토리를 생성하여 socket.io.js 파일을 넣어줍니다.

 

다음과 같이 클라이언트에서 socket.io를 생성할 수 있습니다.

<script src="/socket.io/socket.io.js"></script>
<script>
    var socket;

    var options = {'forceNew':true}; // 기존의 연결을 재사용 할 수 있도록
    var url = 'http://' + host + ':' + port;
    socket = io(url, options);
</script>

socket.io.js를 참조하면 기본적으로 io 전역변수를 같습니다. 그리고 socket = io()로 socket.io를 생성합니다. url과 option을 넣어 줄 수도 있습니다. 서버의 url을 넣으면 서버의 socket.io와 연결됩니다.

 

<script>
    socket.on('connect', () => {
        println('웹소켓 서버에 연결되었습니다. : ' + url);
        console.log('socket.id : ' + socket.id);
    });

    socket.on('disconnect', () => {
        println('웹소켓 연결이 종료되었습니다.');
        console.log('socket.id : ' + socket.id);
    });
</script>

on 메소드로 이벤트를 정의할 수 있습니다. 

 

클라이언트 파일 chat01.html은 다음과 같습니다.

더보기
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>채팅 클라이언트 01</title>

    <script src="jquery-3.1.1.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>

    <script>
        var host;
        var port;
        var socket;

        // 문서 로딩 후 실행됨
        $(function() {

            $("#connectButton").bind('click', function(event) {
                println('connectButton이 클릭되었습니다.');

                host = $('#hostInput').val();
                port = $('#portInput').val();

                connectToServer();
            });

        });

        // 서버에 연결하는 함수 정의
        function connectToServer() {

            var options = {'forceNew':true}; // 기존의 연결을 재사용 할 수 있도록
            var url = 'http://' + host + ':' + port;
            socket = io(url, options); // io는 socket.io.js 에서 선언된 전역변수임

            socket.on('connect', () => {
                println('웹소켓 서버에 연결되었습니다. : ' + url);
                console.log('socket.id : ' + socket.id);
            });

            socket.on('disconnect', () => {
                println('웹소켓 연결이 종료되었습니다.');
                console.log('socket.id : ' + socket.id);
            });

        }

        function println(data) {
            console.log(data);
            $('#result').append('<p>' + data + '</p>');
        }
    </script>
</head>
<body>
<h3>채팅 클라이언트 01</h3>
<br>
<div>
    <input type="text" id="hostInput" value="localhost" />
    <input type="text" id="portInput" value="3000" />

    <input type="button" id="connectButton" value="연결하기" />
</div>

<hr/>
<p>결과 : </p>
<div id="result"></div>

</body>
</html>

 

클라이언트를 실행할 때 jquery 파일이 필요합니다.

jquery-3.1.1.min.js
0.08MB

실행시 모습입니다. 연결하기를 누르면 소켓 서버에 연결합니다.

 

 

Reference

 

 

 

댓글