html 은 일반 채팅과 같은 TCP/IP 프로토콜을 사용하지만, 클라이언에서 서버로 요청을 보내면, 요청에 대한 처리 후 접속을 끊어 버립니다. 그런 이유로 단방향 통신이라하며, 서버에서 원할 때 클라이언트로 메시지를 보낼 방법이 없습니다.
하지만, HTML5에서 웹소켓 개념이 추가되며, 이런 문제를 해결하였습니다. node.js에서 잘 알려진 웹소켓 지원 모듈은 ws 와 socket.io 입니다. 둘다 websocket을 이용할 수 있다는 점은 같지만, 특징이 뚜렸하기 때문에, 사용목적이 달라질 수 있습니다.
ws : 표준 웹소켓을 구현하였습니다. 그래서, 웹 브라우저, 게임을 포함한 앱, 윈도우 프로그램 모든 곳에서 사용할 수 있습니다. 하지만, 구형 웹브라우저나, 웹소켓이 모두 구현되지 않은 곳에서는 잘 동작하지 않을 수 있습니다.
socket.io : 브라우저만을 위한 특화된 방식으로 모듈이 구현되어 있습니다. 그래서 표준 웹소켓이 아니므로, 웹에서만 사용이 가능합니다. 하지만, 웹소켓을 지원하지 않는 브라우저는 polling을 이용해 연결합니다. 즉, 99.99% 브라우저에서 동작합니다.
이 문서는 socket.io의 내용만을 답고 있습니다.
[공식문서]
websocket org : https://www.websocket.org .
socket io : http://socket.io .
[참고문서]
express 구축 : https://nicgoon.tistory.com/234 .
javascript 웹 소켓 클라이언트 : https://nicgoon.tistory.com/227 .
1. express 구축.
이 부분은 따로 설명하지 않습니다. ws 사용법을 집중적으로 다루기 위함 입니다. express를 사용해 본 경험이 없으시다면, 참고 문서의 express 구축 ( 링크 ) 페이지를 따라 구축해 주시면 될 것 같습니다.
2. socek.io를 이용한 route 구축.
- socket.io 모듈을 설치 합니다.
$ npm i socket.io
- 웹소켓을 구현 합니다.
그리고 웹소켓을 처리할 모듈파일 webSocket.js 을 적당한 위치에 만들어 줍니다. 모듈 파일을 생성했다면, 아래와 같이 소스를 만들어 줍니다. (각 소스에 대한 설명은 주석을 달아 두었습니다.). socket.io의 특징은 connect, disconnect, error외에 이벤트를 직접 정의 한다는 것 입니다. 즉 어디로 받을 것인지 선택할 수 있으며, 아래소스에서는 ms라는 이벤트를 추가하였습니다.
const SocketIO = require("socket.io");
module.exports = function ( _server ) {
// 소켓 io를 처리할 객체를 생성합니다.
const io = SocketIO( _server, {path: '/socket.io'} );
// 접속 처리 및 해당 클라이언트에 대한 모든 처리를 합니다.
io.on( "connection", function( socket ){
// 접속한 정보를 표시합니다.
const req = socket.request;
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
console.log( ip + "의 새로운 유저가 접속하였습니다." );
// 접속이 끊어진 경우 처리를 하는 콜백 입니다.
socket.on( "disconnect", function( ){
console.log("접속을 해제 하였습니다.");
});
// 오류가 난 경우 처리를 하는 콜백 입니다.
socket.on( "error", function( error ){
console.log( "error:" + error );
});
// 일반 메시지를 받은 경우의 처리 입니다. (ms 라는 이벤트로 클라이언트가 보낼 때 마다 이 메소드가 호출 됩니다.)
socket.on( "ms", function( data ){
// 클라이언트로 부터 받은 메시지를 표시합니다.
console.log( "클라이언트로 부터 받은 메시지 : " + data );
// 클라이언트에 구현된 echo 이벤트로 메시지를 보내어 줍니다.
socket.emit( "echo", data );
});
});
}
- 구현한 웹소켓을 연결합니다.
그런다음 모듈을 http 서버에 연결해 줍니다. (express 같은 경우 listen을 통해 만들어진 서버, http의 경우 createServer 메소드로 만들어진 서버). 위에 링크된 express 구축을 따라했다면, /bin/www 파일속에 server 객체가 정의 되어 있습니다. 적당한 위치에 아래와 같이 웹소켓을 연결하도록 합니다.
const webSocket = require( "../routes/webSocket" );
webSocket( server );
3. 브라우저를 통해 웹소켓 서버에 접속해 보기.
- 지금까지 구현한 서버 실행.
$ npm start
- 클라이언트 만들고 호출 하기.
테스트할 웹브라우저에 아래 소스를 추가합니다. 웹에서 우리가 만든적 없는 js 파일 "/socket.io/socket.io.js" 파일을 추가하는데, express 서버에 socket.io를 구현하였다면, 자동으로 추가되어 다운로드 받을 수 있습니다. 그리고, 서버와 마찬가지로, 받는 이벤트명을 마음대로 정할 수 있습니다. 특징은 접속을 따로 하거나, 연결을 따로 하지 않습니다. 끊어지면 바로 자동으로 새 접속을 시도합니다. (언제나 연결을 유지 합니다.)
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script src="/socket.io/socket.io.js"></script>
<script>
// 웹소켓 서버를 설정합니다.
var socket = io.connect( "http://localhost:3000" , {path: "/socket.io"} );
socket.on( 'echo', function( data ){
console.log( data );
writeToScreen( "받은메시지:" + data )
});
// 서버로 데이터를 보내기 위한 메소드 입니다.
function sendMessage( )
{
// 서버에 구현된 ms 이벤트로 메시지를 보냅니다.
mss = document.getElementById( "message" ).value;
socket.emit( "ms", mss );
}
// 받은 메시지를 출력합니다.
function writeToScreen(message)
{
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
</script>
<h2>소켓 io 동작을 테스트 하기 위한 node js 입니다.</h2>
<form>
<input id="message" /> <button type="button" onclick="sendMessage();" >전송</button><br>
</form>
<div id="output"></div>
- 브라우저 호출.
브라우저에서 위의 소스를 실행하면, node.js에 아래와 같은 메시지를 볼 수 있습니다. (자동으로 바로연결됨)
- 메시지 보내기.
브라우저에서 적당한 메시지를 입력하고, 전송 버튼을 눌러 봅니다.
그러면 아래와 같이, 메시지를 되돌려 받았을 것 입니다.
서버의 상태를 보면, 아래와 같이 클라이언트가 접속했음을 확인할 수 있습니다.
그리고 브라우저를 닫으면, 서버에서 접속이 끊어진 메시지 또한 확인할 수 있습니다.
'Node.js' 카테고리의 다른 글
NodeJS 페이팔 결제 연동 (Checkout, SDK) (0) | 2019.07.29 |
---|---|
nodejs를 이용한 paypal 결제 연동하기 (구독) (1) | 2019.07.14 |
node.js ws 를 이용한 웹소켓 구현. (6) | 2019.06.02 |
Express-generator로 express 간단히 셋팅하기. (0) | 2019.06.02 |
node js 파일 업로드 multer (field) (0) | 2019.06.01 |