Node.js로 채팅창 구현하기

Web socket의 등장

원래 기존의 웹기반의 기술에서는 html문서를 주고받는 다운로드기반의 http 프로토롤을 쓰기 때문에
실시간 연결이 유지되지 않았습니다. 즉, http를 사용하는 웹은 상태를 유지하지 못하기 때문에
stateless하다고 표현합니다.

따라서 채팅과 같이 서버와 클라이언트가 지속적인 연결을 유지하는 기술은 구현이 불가능하였습니다.
그렇게 때문에 , 채팅을 제작하려면 java, c, c#과 같은 응용 프로그램을 이용해야 했습니다.

그러나 HTML5에서 지원하는 Web Socket과 Node.js의 socket.io를 사용하면 웹상에서도 실시간 통신이
가능합니다. 즉, stateful한 것이라고 볼 수 있습니다.

하지만 주의할 점이 있습니다. 웹소켓과 socket.io는 java, c#과 같은 언어에서 지원하는 소켓과는 틀리기 때문에
반드시 웹서버 위에서 구동됩니다.
따라서 기존에 node.js에서 구현하였던 웹서버 객체들은 그대로 사용해야 합니다.

node js로 채팅창 구현하기

이전 포스팅에서 짰던 코드를 다시 복습해봅시다.

webserver1파일 안에 chatServer.js파일을 생성하고 아래 코드를 입력합니다.

1
2
3
4
5
6
7
8
9
10
11
var http = require("http"); //http객체 생성
var express = require("express"); //express외부모듈 객체로 받기
var app = express(); //express생성자 객체생성
var server = http.createServer(app); // 기존 웹 서버 업그레이드


app.use(express.static(__dirname)); //클라이언트의 요청마다 조건문으로 라우팅 처리할 필요없음.

server.listen(8989, function(){ //이번에는 8989포트에서 서버가동
console.log("웹서버 8989에서 가동중...");
})

8989에서 가동하는 web server를 만들었습니다.

이제 실시간 통신이 가능한 socket server를 만들어 보겠습니다. 이는 웹서버를 기반으로 돌아가기때문에
반드시 기존의 web server도 필요하다는 점을 잊으면 안됩니다!!

1
var socketio = require("socket.io");

socket.io는 외부모듈이기 때문에

1
npm install socket.io

설치를 꼭 해주어야 합니다.

socket은 개발자가 네트워크에 대한 지식없이 단지, socketio라는 모듈을 메모리에 올려두고
메소드를 통해 조작만 하면 쉽게 구현할 수 있습니다.

웹소켓은 웹기반 가상소켓이기 때문에 반드시 웹브라우저 클라이언트들만 접속이 가능합니다.
반면, Net이라는 모듈은 브라우저이외의 어떤 형태의 클라이언트건 다 인식할 수 있습니다.
** Net Module : TCP 프로토콜 기반의 소켓 프로그래밍을 지원하는 코어 모듈.

채팅화면을 구현한 client1.html이라는 파일을 webserver1에 만듭니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>접속클라이언트</title>
<style>
.wrapper{
width: 350px;
background: steelblue;
}
.top{

}
.top > input{
width: 98%;
font-size: 25px;
background: dodgerblue;
color: white;
font-weight: bold;
}
.content > textarea{
width: 98%;
height: 250px;
}
.footer>input{
width: 98%;
height: 30px;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var socket; //대화용 소켓생성

$(function(){
//버튼누르면 노드서버에 소켓을 통해 접속!
$("#bt").click(function(){
socket = io(); //접속이 성공되면, 대화용 소켓이 반환됨!!
//서버가 보낸 데이터 받기!!
socket.on("message",function(data){
//textarea에 출력한다.
var area = document.getElementById("area");
area.append(data.msg+"\n");
})
});
});
//연결되어있는 서버에 메세지 보내기
function enter(obj){
if(event.keyCode === 13){
//메세지를 보내는 이벤트
socket.emit("message", {"msg":""+obj.value+""});
obj.value=""; //입력한 글씨 다시 지우기
}
}
</script>
</head>
<body>
<div class="wrapper">

<div class="top">
<input type="button" value="접속" id="bt">
</div>
<div class="content">
<textarea id="area"></textarea>
</div>
<div class="footer">
<input type="text" onkeyup="enter(this)">
</div>


</div>
</body>
</html>


접속버튼을 클릭하면 노드 서버에 접속을 시도하고, 성공하면 대화용 socket을 반환합니다.
그리고 클라이언트가 입력창에 텍스트를 치고 엔터키를 누르면
enter함수가 호출되면서 연결되어있는 서버에 텍스트를 포함한 메시지가 전송됩니다.

이제, 소켓 서버를 가동시키고 , 접속자들을 감지합니다.

1
2
3
4
5
var io = socketio.listen(server); //소켓 서버를 가동!
console.log("소켓서버도 가동");
io.sockets.on("connection",function(socket){ //sockets는 접속을 걸어온 접속자들을 의미!
console.log("접속자 발견!!");
})

접속자들의 socket들을 담을 배열객체를 생성하고,
소켓에 접속할 때마다 배열에 socket을 담습니다.
그리고 클라이언트가 emit()으로 data를 보냈다면, 받는 쪽에서는 on으로 받습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var socketArray = new Array();

//접속한 자의 소켓 배열에 담기!
socketArray.push(socket);
console.log("대화 참여자는 총 %d명",socketArray.length);

//받는 접속자는 on으로 받는다.
socket.on("message",function(data){
console.log(data);
//방금 전달받은 메세지를 곧바로 다시 클라이언트에게 보낸다.
for(var i = 0; i< socketArray.length; i++){

socketArray[i].emit("message", data);
};
});

그럼 client.html에서는 서버가 곧바로 보낸 메세지를 받아서
textarea에 출력합니다.

이번 포스팅에서는 간단하게 웹소켓과 node.js를 이용한 stateful한 웹채팅창을 구현해 보았습니다.
다음 포스팅은 node.js서버와 database 연동 작업을 하겠습니다.

Share