'html5'에 해당되는 글 2건

  1. 2019.06.03 node.js socket.io 를 이용한 소켓 구현
  2. 2019.05.01 javascript 웹소켓 클라이언트

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에 아래와 같은 메시지를 볼 수 있습니다. (자동으로 바로연결됨)

 

- 메시지 보내기.

브라우저에서 적당한 메시지를 입력하고, 전송 버튼을 눌러 봅니다.

 

그러면 아래와 같이, 메시지를 되돌려 받았을 것 입니다.

 

서버의 상태를 보면, 아래와 같이 클라이언트가 접속했음을 확인할 수 있습니다.

 

그리고 브라우저를 닫으면, 서버에서 접속이 끊어진 메시지 또한 확인할 수 있습니다.

 

 

 

 

 

 

 

 

Posted by 창업닉군
,

HTML5와 웹소켓이 나오기 전까지, 홈페이지는 그저 요청에 대한 서버 결과를 돌려 주는 형태로만 제작이 가능했습니다. 물론 여러가지 방법을 통해, 비슷한 형태로 제작이 가능했지만, 근본적인 대책은 아니였습니다. TCP/IP 통신을 하지 못해, 챗팅 게임등의 서버로 사용하기 힘들었지만, 웹소켓이 나온 이후로는 매우 편리해 졌습니다.

거기다, 쉬운 방식으로 구현히 가능해, 적어도 한 시간 이내에 기능을 구현하는 것이 가능합니다. 제가 TCP, UDP통신을 모두 구현해 보았지만, 웹소켓만큼 구현히 쉽지는 않았습니다.

이 문서에는 javascript를 통한, 클라이언트를 구현해 보도록 하겠습니다. websocket.org 라는 사이트에서 웹소켓 에코 서버를 지원해 주므로, 클라이언트 부터 만들고, 이 클라이언트를 바탕으로 서버를 만들면 서버 또한 깔금하게 만들수 있습니다.

 

[공식문서]

공식 사이트 : websocket org : https://www.websocket.org .

 

 

1. 샘플 보기 및 샘플 테스트.

공식 사이트에 가면, 샘플에 대한 구현 방법과 에코서버를 어떻게 테스트 하는지 잘 설명하고 있습니다.

먼저, 공식 사이트로 이동합니다. ( 링크 ) 그럼, 아래와 같이 페이지가 나오는데 화면 중앙의 GET STARTED 버튼을 눌러 주도록 합니다.

그럼 에코 테스트 페이지가 나옵니다. 화면 중앙의 녹색 This browser supports WebSocket 이라는 문구는, 여러분이 사용하는 브라우저가 웹소켓을 지원하고 있음을 알려주고 있습니다. 요즘은 거의 모든 브라우저가 웹소켓을 지원하지만, 얼마전까지만 해도 그렇지 않았습니다.

원할한 서비스를 위해 여러분도 여려분의 홈페이지에 방문자의 브라우저가 웹소켓을 지원하는지 여부를 알려줄 필요가 있을 지 모릅니다. (구현은 간단합니다.) location: 부분에 입력된 값은 테스트를 위한 에코서버의 주소 입니다. 일단 그대로 두고, 컨넥트 버튼을 눌러 보도록 하겠습니다.

그럼 에코 서버와 연결이 되어 Log에, CONNECTED라고 표시됩니다.

메시지 부분에 적당한 메시지를 입력하고, Send를 눌러 보도록 하겠습니다.

그럼 아래와 같이 보낸 메시지를 서버가 그대로 돌려 줍니다.

마지막으로 서버와의 접속을 끊어주는 Disconnect 를 눌러 주도록 합니다.

그럼 아래와 같이 DISCONNECTED 라는 로그가 남기며 접속이 종료됩니다.

간단한 기능이지만, 챗팅 및 게임을 구현하기에 충분한 역할을 하고 있는 것을 확인할 수 있습니다. 하지만, 이렇게 구현하는데, 코드 몇 줄으면 끝이난다는 것이 더 매력적입니다.

 

 

 

2. 소스 보기.

위의 페이지에서 아래로 스크로를 해 보면, 위 코드에 대해서 간단히 구현해 놓은 코드를 제공합니다.

워낙 소스가 잘되어 있어서, 따로 무언가를 할 필요가 없어서, 공식예제에 주석만 달아 아래에 소스를 공개합니다.

  <!DOCTYPE html>
  <meta charset="utf-8" />
  <title>WebSocket Test</title>
  <script language="javascript" type="text/javascript">

  var wsUri = "wss://echo.websocket.org/";
  var output;

  // DOM 이 형성되었을 때 가장 먼저 호출되는 메소드 입니다.
  function init()
  {
    output = document.getElementById("output");
    testWebSocket();
  }

  // 서버와의 접속을 시작하는 메소드 입니다.
  function testWebSocket()
  {
  
    // 지정한 주소로 웹소켓 연결을 시도하는 코드 입니다.
    websocket = new WebSocket(wsUri);
    
    // 웹소켓의 각 이벤트에 대한 처리 메소드들을 연결한 코드들 입니다.
    // 위의 호출 이후 이벤트를 연결해도 문제가 없는 이유는 위의 웹소켓은 콜백 처리를 하게되는데,
    // 콜백으로 호출되는 메소드들은 무조건 다음 프레임에 처리됩니다. 그래서 뒤에 호출해도 됩니다.
    websocket.onopen = function(evt) { onOpen(evt) };
    websocket.onclose = function(evt) { onClose(evt) };
    websocket.onmessage = function(evt) { onMessage(evt) };
    websocket.onerror = function(evt) { onError(evt) };
    
    
  }

  // 서버와 접속이 완료되었을 때 호출되는 메소드 입니다.
  function onOpen(evt)
  {
    writeToScreen("CONNECTED");
    doSend("WebSocket rocks");
  }

  // 어떤 이유로든 서버와의 접속이 종료되었을 때, 호출되는 메소드 입니다.
  function onClose(evt)
  {
    writeToScreen("DISCONNECTED");
  }

  // 메시지를 받았을 때, 처리하는 메소드 입니다.
  function onMessage(evt)
  {
    writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>');
    websocket.close();
  }

  // 에러가 발생했을 때, 처리 메소드 입니다.
  function onError(evt)
  {
    writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
  }

  // 서버로 메시지를 보냅니다.
  function doSend(message)
  {
    writeToScreen("SENT: " + message);
    websocket.send(message);
  }

  // 로그에 메시지를 남겨 줍니다.
  function writeToScreen(message)
  {
    var pre = document.createElement("p");
    pre.style.wordWrap = "break-word";
    pre.innerHTML = message;
    output.appendChild(pre);
  }

  // 브라우저의, DOM 구성이 완료되면, 가장 먼저 실행할 메소드를 지정하는 메소드 입니다.
  // (즉, 가장 먼저 실행될 메소드 지정).
  window.addEventListener("load", init, false);

  </script>

  <h2>WebSocket Test</h2>

  <div id="output"></div>

 

 

 

 

 

 

 

 

 

 

 

Posted by 창업닉군
,