본문 바로가기
Programming/>> Node.js

[node.js] node.js를 이용한 웹소켓 통신 - 채팅

by 니키ᕕ( ᐛ )ᕗ 2016. 3. 16.

 

원래 서버와 클라이언트(브라우저)가 통신을 할때는 HTTP(Hyper Text Transfer Protocol)을 이용하고 1개의 요청이 가면 1개의 응답이 오는 것이 일반적이다.

 

1. 만약 네이버(www.naver.com)를 주소창에 입력하면 브라우저는 인터넷에 접속하여 DNS서버를 거친 뒤 네이버 서버에 도달하게 되고 www.naver.com 주소가 가리키는 파일을 요청한다. 

2. 이 요청을 받은 네이버의 서버는 url 분석후index.html(네이버 메인 화면을 index.html라고 가정) 파일을 브라우저에 전송하게 된다.

3. 브라우저는 파일을 받고 화면에 띄울 준비를 한다. 위에서부터 문서를 읽다보면 참조 주소가 네이버인 css파일이 있다. 그렇다면 네이버 서버에 다시 접근 후 요청하여 css파일을 받고 캐시에 넣는다.

4. 그다음에 내려갔더니 이번엔 js파일이 필요하다. 3번의 작업을 반복한다.

5. 페이지 로드가 끝날 때까지 이런 모든 파일을 받아오는데에 1요청(리소스요청) 1응답(파일받음)으로 처리가 된다.

 

html5 icon

그러다 모바일 환경의 등장으로 웹의 활용도가 높아졌고, 굳이 웹에서는 실시간 전송에 대한 필요성이 없었으나(있어도 거의 어도비 플래시로 처리했다. 내가 알기로는) 그리고 HTML5버전에서 web socket이 등장했다.

 

웹소켓의 개념 자체는 별거 없다. 응답 하나에 요청 하나만 처리하면 해당 응답에 대한 작업은 땡치던 것을 이제 통로하나 뚫어놓고 기다리는 것이다. 

서버는 (서버)소켓을 가지고 있고 클라이언트가 요청하면 서버소켓중 하나가 해당 클라이언트의 몫이 된다. 서버의 통신 대역폭 일부를 점유하게 된다.

아무래도 최근에 적용된 기술이다보니 지원을 안하는 브라우저나 버전이 있을 수 있다. 특히 IE라던가 IE라던가 IE라던가............. 

본인이 사용하는 브라우저가 웹소켓을 지원하는지는 http://www.websocket.org/echo.html 이곳에서 확인할 수 있다. 최신 브라우저라면 왠만하면 될 것...

 

그리고 내가 이 포스팅을 쓰는 이유는............. 이전에 학원에서 다른팀이 했던 프로젝트를 구현해보고 싶어서이다. 

canvas와 web socket을 이용하여 실시간으로 그림을 그릴 수 있는 것..

다른 언어(java?)도 웹소켓을 지원하긴 하는데 node.js를 한번 써보고 싶어서 java는 제외시켰다.

 

1.

- node.js는 https://nodejs.org/ko/에서 받아서 설치한뒤 시스템 PATH에 설치경로만 추가해주면 설정이 끝난다. 매우 간단

 

2.

- socket.io 패키지를 받는다. cmd창을 열고 > npm install socket.io를 입력하면 패키지 설치가 완료된다.

 

3.

socketio.js

var http = require('http');
var fs = require('fs');
var socketio = require('socket.io');

var server = http.createServer(function(req, res){
		fs.readFile('index.html', function(err, data){
		res.writeHead(200, {'Content-Type':'text/html'});
		res.end(data);
	});
}).listen(8080, function(){
	console.log('Running ~~~~~~~~~~~~');
});

var io = socketio.listen(server);
io.sockets.on('connection', function(socket){
		socket.on('sMsg', function(data){
		io.sockets.emit('rMsg', data);
	});
});
- 자바는 클래스나 패키지를 참조할 때 import를 사용하지만 node.js는 require함수를 사용하여 패키지를 불러온다. 위의 코드에서 http는 웹 서버를 구성하기 위해 필요하고, fs는 file system의 약자로 파일을 읽어들일 때 사용한다. 
- 우선 http을 이용하여 서버를 생성한다. 생성 후 콜백함수에는 무엇을 할지가 들어가있는데, 위의 코드에선 index.html을 파일시스템에서 읽어와 응답으로 보낸다. server객체의 listen함수를 이용하면 그 순간부터 웹서버로 동작하기 시작한다. listen함수의 첫번째 파라미터는 포트넘버이고 두번째는 콜백함수로 난 그냥 서버가 켜졌음을 표시했다.
- socket.io 패키지를 불러온 뒤, listen함수에 기동할 웹서버 객체를 파라미터로 넘기고 io.sockets.on는 해당 서버소켓 전체에게 이벤트를 적용시킨다.
- 'connection' 이벤트가 발생하면 콜백함수에 연결 후의 이벤트 설정을 지정한다. 위의 코드에서는 개별 소켓에 sMsg라는 이벤트가 발생하면 받은 데이터를 전체 서버소켓에 rMsg라는 이벤트를 발생시키고 데이터를 전달한다.
 

 

index.html

<!DOCTYPE>
<html>
<head>
	<style>
		#container {
			width: 400px;
	    border: 1px dotted #000;
	    padding: 10px;
	    height: 328px;
		}
		#chatBox {
			border: 1px solid #000;
	    width: 400px;
	    height: 300px;
			margin-bottom: 5px;
		}
		#chat li {
			padding: 5px 0px;
		}
		#name {
	    width: 78px;
		}
		#msg {
	    width: 256px;
		}

	</style>
	<script type="text/javascript" src="https://cdn.socket.io/socket.io-1.0.0.js"></script>
	<script type="text/javascript">
		window.onload = function(){
			var socket = io.connect();
			if(socket != null && socket != undefined){
				var welcome = document.createElement('li');
				welcome.innerHTML = '<system> 채팅을 시작합니다.';
				document.getElementById('chat').appendChild(welcome);

				socket.on('rMsg', function(data){
					var li = document.createElement('li');
					li.innerHTML = data.name + ' : ' + data.msg;
					document.getElementById('chat').appendChild(li);
				});

				document.getElementById('submit').onclick = function(){
					var val = document.getElementById('msg').value;
					var name = document.getElementById('name').value;
					socket.emit('sMsg', {
						name : name,
						msg : val
					});
					document.getElementById('msg').value = '';
				};

			}
		};
	</script>
</head>
<body>
<div id="container">
	<div id="chatBox">
		<ul id="chat"></ul>
	</div>
	<input type="text" id="name"/>
	<input type="text" id="msg"/>
	<button id="submit">보내기</button>
</div>
</body>
</html>
- socket.io.js 파일을 링크시킨다. 내가 본 책에서는 서버단에서 socket.io를 포함시키면 자동으로 추가되어있을거라고 하는데 걍 별도로 추가해야됨..
- io.connect를 통해 서버소켓에 연결 후, 소켓을 통해 rMsg가 발생하면 채팅창에 메세지를 뿌린다.
- 보내기 버튼에 클릭이벤트를 설정하여 sMsg이벤트를 발생시키고 사용자 이름과 메세지를 객체 형식으로 서버에 전송한다.
 
- emit은 이벤트를 발생시키고 on은 이벤트를 기다린다.

 

 

4. 

localhost:8080으로 첫 진입하면 이렇게 뜬다. 브라우저를 2개 띄운 후 하나는 이름부분을 1, 다른 하나는 2로 설정한 후 채팅 메세지를 전송하였다.

 

 

일단은 간단한거라 적용은 잘 됐다... 사실 책에 나와있는건데 간단하지만 걍 복습할겸 써봄

 

 

 

댓글