
Client: JavaScript + WebSocket
Server: NodeJS
nodejs
https://nodejs.org/ko/
vscode
https://code.visualstudio.com





















== JS01_Variable.js ==
// var => 변수 선언
var A = 'NolBu';        // ; 는 생략 가능
console.log('A=> ' + A + ', typeof(A)=>' + typeof(A));
A = 10;
console.log('A=> ' + A + ', typeof(A)=>' + typeof(A));
var A = true;           // 동일한 이름으로 재 선언 => 에러 아님
console.log('A=> ' + A + ', typeof(A)=>' + typeof(A));
console.log('');
// let => 변수 선언 ES2015(es6) 버전을 지원하는 브라우저만 사용 가능
let B = 'HungBu';
console.log(`B=> ${B}, typeof=> ${typeof(B)}`); // ES2015(es6)
B = 20;
console.log(`B=> ${B}, typeof=> ${typeof(B)}`); 
// let B = 'HungBu';  // 변수의 재 선언은 에러
// console.log(`B=> ${B}, typeof=> ${typeof(B)}`); // ES2015(es6)
console.log('');
// const => ES2015(es6)
// 상수, Java => final
const C_VALUE = 3.14;
console.log(`B=> ${C_VALUE}, typeof=> ${typeof(C_VALUE)}`); 
// C_VALUE = 100; // 값 변경 안됨
console.log(window);
//var alert = 10; // 내장 객체에 다른 값을 대입
// 그 이후로는 사용 못함
//window.alert('Hello World')
== JS.html ==
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript</title>
    <script type="text/javascript" src="js01_Variable.js"></script>
</head>
<body>   
</body>
</html>














npx babel js01_Variable.js --out-dir dist


npx babel fileName --out-dir dist 
npx babel folderName\fileName --out-dir dist


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <title>WebSocket</title>
  <script type="text/javascript">
   /*
    window.onload = function()
    {
      var input = document.getElementById('view')
      console.log(input);
    }
    */
    
    function init()
    {
       // 지원 여부 체크
      if(!window.WebSocket) {
        window.alert('WebSocket을 지원하지 않습니다.\n다른 브라우저를 이용해 주세요.')
      }
      // Dom 읽어오기
      var view = document.getElementById('view');      
      var sendBtn = document.getElementById('sendBtn');
      var stopBtn = document.getElementById('stopBtn');
      var status = document.getElementById('status');
      // HTML5 기본 API라 바로 사용 가능
      var ws = new WebSocket('ws://echo.websocket.org')
      // 연결되면 딱 1번 실행되는 이벤트
      ws.onopen = function(evt){
        console.log('Connected WebSocket ', evt);
        status.innerHTML = '<b style="color:orange;">WebSocket Connected</b>';
      }
      // 연결 종료, stopBtn을 클릭하면 종료
      stopBtn.addEventListener('click', function(){
        if(ws.readyState === WebSocket.OPEN){
          ws.close();   // 서버에 종료를 알림
        }      
      });
      
      // 끊으면 서버에서 끊었다는 이벤트를 전달
      // 클라이언트에서는 이 이벤트를 받아 처리
      ws.onclose = function(evt){
        console.log('Closed WebSocket ', evt);       
        var code = evt.code;
        var reason = evt.reason;
        var wasClean = evt.wasClean;
        
        if(wasClean){
          // 정상 종료 되거나
          status.innerHTML = status.innerHTML + '<br><b style="color:orange;">WebSocket Closed</b>';
        }else{
          // 비 정상 종료 되거나
          status.innerHTML = status.innerHTML + '<br><b style="color:orange;">WebSocket Closed Message ' + reason + ', Code: ' + code + ' </b>';
        }    
      }
      
      // onerror
      ws.addEventListener('error', function(evt){
        console.log('Error ', evt);
        status.innerHTML = status.innerHTML + '<br><b style="color:red;">Error...</b>';
      });
      // 버튼을 클릭하면 input 값을 뽑아 서버에 전달
      sendBtn.addEventListener('click', function(){
        var value = view.value;
        ws.send(value);   // string
        view.value = '';
        view.focus();
      });
      // 내가 보낸 값을 서버에서 처리 후 나에게 다시 send하면
      // 그 값을 받아 처리
      ws.addEventListener('message', function(evt){
        console.log('Message => ', evt);
        status.innerHTML = status.innerHTML + '<br><b style="color:gray;">' + evt.data + '</b>';
      })
    }
    window.addEventListener('load', init)
  </script>>
</head>
<body>
  <div class="card-body">
    <h3>WebSocket</h3>
    <br>
    <input type="text" class="form-control" id="view">
    <br>
    <button class="btn btn-primary" id="sendBtn">SEND</button>
    <button class="btn btn-primary" id="stopBtn">STOP</button>
    <br>
    <div id="status">Status</div>
  </div>
</body>
</html>

npm i ws

// ws02_server.js
// node용 WebSocket lib가 필요
// 설치
// npm i ws
// ctrl + `
// 라이브러리 불러오기
const WebSocket = require('ws');
// websocket 서버
const wss = new WebSocket.Server({
    port: 3000
});
// Node에서는 이벤트를 on으로 처리\
wss.on('connection', function(ws){
    // 모든 처리는 이 connection 내부에서 처리한다. 
    // 연결되면 open이벤트를 client에 전달한다.
    console.log('Server Connected...');
    ws.send('Hello World');     // client 의 message event가 받게 된다.
    // client에서 넘어온 메시지를 받아 편집(여기서는 안함)해서 클라이언트에 전달
    ws.on('message', (evt) => {
        console.log(evt); // clg
        ws.send('Server=> ' + evt)
    })
    ws.on('close', (code, meg) => {
        console.log(`WebSocket Closed Code: ${code}, Msg: ${msg}`);
    });
    
    ws.on('error', (err) => {
        console.log('Server Error', + err);
    })
});

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <title>WebSocket</title>
  <script type="text/javascript">
   /*
    window.onload = function()
    {
      var input = document.getElementById('view')
      console.log(input);
    }
    */
    function init()
    {
       // 지원 여부 체크
      if(!window.WebSocket) {
        window.alert('WebSocket을 지원하지 않습니다.\n다른 브라우저를 이용해 주세요.')
      }
      // Dom 읽어오기
      var view = document.getElementById('view');      
      var sendBtn = document.getElementById('sendBtn');
      var stopBtn = document.getElementById('stopBtn');
      var status = document.getElementById('status');
      // HTML5 기본 API라 바로 사용 가능
      //var ws = new WebSocket('ws://echo.websocket.org')
      var ws = new WebSocket('ws://localhost:3000')
      // 연결되면 딱 1번 실행되는 이벤트
      ws.onopen = function(evt){
        console.log('Connected WebSocket ', evt);
        status.innerHTML = '<b style="color:orange;">WebSocket Connected</b>';
      }
      // 연결 종료, stopBtn을 클릭하면 종료
      stopBtn.addEventListener('click', function(){
        if(ws.readyState === WebSocket.OPEN){
          ws.close();   // 서버에 종료를 알림
        }
      });
      // 끊으면 서버에서 끊었다는 이벤트를 전달
      // 클라이언트에서는 이 이벤트를 받아 처리
      ws.onclose = function(evt){
        console.log('Closed WebSocket ', evt);        
        var code = evt.code;
        var reason = evt.reason;
        var wasClean = evt.wasClean;
        if(wasClean){
          // 정상 종료 되거나
          status.innerHTML = status.innerHTML + '<br><b style="color:orange;">WebSocket Closed</b>';
        }else{
          // 비 정상 종료 되거나
          status.innerHTML = status.innerHTML + '<br><b style="color:orange;">WebSocket Closed Message ' + reason + ', Code: ' + code + ' </b>';
        }
      }
      // onerror
      ws.addEventListener('error', function(evt){
        console.log('Error ', evt);
        status.innerHTML = status.innerHTML + '<br><b style="color:red;">Error...</b>';
      });
      // 버튼을 클릭하면 input 값을 뽑아 서버에 전달
      sendBtn.addEventListener('click', function(){
        var value = view.value;
        ws.send(value);   // string
        view.value = '';
        view.focus();
      });
      // 내가 보낸 값을 서버에서 처리 후 나에게 다시 send하면
      // 그 값을 받아 처리
      ws.addEventListener('message', function(evt){
        console.log('Message => ', evt);
        status.innerHTML = status.innerHTML + '<br><b style="color:gray;">' + evt.data + '</b>';
      })
    }
    window.addEventListener('load', init)
  </script>>
</head>
<body>
  <div class="card-body">
    <h3>WebSocket</h3>
    <br>
    <input type="text" class="form-control" id="view">
    <br>
    <button class="btn btn-primary" id="sendBtn">SEND</button>
    <button class="btn btn-primary" id="stopBtn">STOP</button>
    <br>
    <div id="status">Status</div>
  </div>
</body>
</html>

// ws02_server.js
// node용 WebSocket lib가 필요
// 설치
// npm i ws
// ctrl + `
// 라이브러리 불러오기
const WebSocket = require('ws');
// websocket 서버
const wss = new WebSocket.Server({
    port: 3000
}); 
// Node에서는 이벤트를 on으로 처리\
wss.on('connection', function(ws){
    // 모든 처리는 이 connection 내부에서 처리한다. 
    // 연결되면 open이벤트를 client에 전달한다.
    console.log('Server Connected...');
    ws.send('Hello World');     // client 의 message event가 받게 된다.
    
    // client에서 넘어온 메시지를 받아 편집(여기서는 안함)해서 클라이언트에 전달
    // client data 형식 => {event: 'open', data: 'Hello World'}
    ws.on('message', (evt) => {
        var clientData = JSON.parse(evt);   // JSON => JavaScript 객체
        console.log('Serve Messsage', clientData); // clg
        //ws.send('Server=> ' + evt); 
        var sendData; 
        switch(clientData.event){
            case 'open': // {event: 'open', data: 'USER22'}
                    ws.userName = clientData.data;
                    sendData = {event: 'open', data: ws.userName};
                    ws.send( JSON.stringify(sendData));
                break;
            case 'close':  // {event: 'close', data: 'USER22'}
                //ws.userName = clientData.data;
                sendData = {event: 'close', data: ws.userName};
                ws.send( JSON.stringify(sendData));
                break;
            case 'chat':  // {event: 'chat', data: 'Some Message'}
                //ws.userName = clientData.data;
                sendData = {event: 'chat', data: {userName: ws.userName, msg: clientData.data}};
                ws.send( JSON.stringify(sendData));
                break;
        }
    });
    ws.on('close', (code, msg) => {
        console.log(`WebSocket Closed Code: ${code}, Msg: ${msg}`);
    }); 
    ws.on('error', (err) => {
        console.log('Server Error', + err);
    });
});
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebSocket Client</title>
  <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script type="text/javascript">
    var output;
    var userName;
    var sendData;
    function makeDom(msg){
      var p = document.createElement('p');
      p.innerHTML = msg;
      p.style.wordWrap = 'block-word';
      output.appendChild(p);
    } 
    function init() {
      var ws = new WebSocket('ws://localhost:3000');     
      // open 
      ws.addEventListener('open', function(evt){
        userName = 'USER' + Math.floor(Math.random() * 100);
        sendData = {event: 'open', data: userName};
        ws.send(JSON.stringify(sendData)); // JavaScript 객체 => JSON(문자열)로 변환
      }); 
      ws.addEventListener('close', function(evt){
        console.log('Client 정상 종료');
      }); 
      ws.addEventListener('error', function(evt){
      }); 
      ws.addEventListener('message', function(evt){
          console.log('client Message', evt);
          var serverData = JSON.parse(evt.data);
          var dom; 
          switch(serverData.event){
            case 'open':  // {event: 'open', data: 'USER22'}
              dom = '<span style="color:orange;">' + serverData.data + '님이 방문하셨습니다.</span>';
              makeDom(dom);
              break;
            case 'close':  // {event: 'close', data: 'USER22'}
              dom = '<span style="color:orange;">' + serverData.data + '님이 나가셨습니다.</span>';
              makeDom(dom);
              break;
            case 'chat':  // {event: 'chat', data: {userName: 'USER22', msg:'Some Msg'}}
              dom = '<span style="color:gray;">' + serverData.data.userName + ': ' + serverData.data.msg + '</span>';
              makeDom(dom);
              break;
          }
      }); 
      output = document.getElementById('output'); 
      document.getElementById('sendBtn').addEventListener('click', function(){
          var field = document.getElementById('data'); 
          sendData = {event: 'chat', data:field.value};
          ws.send(JSON.stringify(sendData)); 
          field.value='';
          field.focus();
      });     
      document.getElementById('closeBtn').addEventListener('click', function(){
        sendData = {event: 'close', data: userName}
        ws.send( JSON.stringify(sendData));
        ws.close(1000, '정상 종료'); 
      });
    }
    
    window.addEventListener('load', init); 
  </script>
</head>
<body>
  <div class="card-body">
    <h3>WebSocket</h3>
    <hr>
    <div id="output"></div>
    <div class="input-group">
      <input type="text" class="form-control" id="data">
      <div class="input-group-append">
        <button class="btn btn-danger" id="sendBtn">SEND</button>
      </div>
    </div>
    <br>
    <button class="btn btn-primary" id="closeBtn">종료</button>
  </div>
</body>
</html>

// ws02_server.js
// node용 WebSocket lib가 필요
// 설치
// npm i ws
// ctrl + `
// 라이브러리 불러오기
const WebSocket = require('ws');
// websocket 서버
const wss = new WebSocket.Server({
    port: 3000
});
// Node에서는 이벤트를 on으로 처리\
wss.on('connection', function(ws){
    // 모든 처리는 이 connection 내부에서 처리한다. 
    // 연결되면 open이벤트를 client에 전달한다.
    console.log('Server Connected...');   
    ws.send('Hello World');     // client 의 message event가 받게 된다.
    // client에서 넘어온 메시지를 받아 편집(여기서는 안함)해서 클라이언트에 전달
    // client data 형식 => {event: 'open', data: 'Hello World'}
    ws.on('message', (evt) => {
        var clientData = JSON.parse(evt);   // JSON => JavaScript 객체
        console.log('Serve Messsage', clientData); // clg
        
        //ws.send('Server=> ' + evt);
        var sendData;
        switch(clientData.event){
            case 'open': // {event: 'open', data: 'USER22'}
                    ws.userName = clientData.data;
                    sendData = {event: 'open', data: ws.userName};
                    //ws.send( JSON.stringify(sendData));
                    wss.clients.forEach( (client) => {
                        client.send( JSON.stringify(sendData));
                    })
                break;
            case 'close':  // {event: 'close', data: 'USER22'}
                //ws.userName = clientData.data;
                sendData = {event: 'close', data: ws.userName};
                //ws.send( JSON.stringify(sendData));   
                wss.clients.forEach( (client) => {
                    client.send( JSON.stringify(sendData));
                })
                break;
            case 'chat':  // {event: 'chat', data: 'Some Message'}
                //ws.userName = clientData.data;
                sendData = {event: 'chat', data: {userName: ws.userName, msg: clientData.data}};
                //ws.send( JSON.stringify(sendData));               
                wss.clients.forEach( (client) => {
                    client.send( JSON.stringify(sendData));
                })
                break;
        }
    });
    ws.on('close', (code, msg) => {
        console.log(`WebSocket Closed Code: ${code}, Msg: ${msg}`);
    });
    ws.on('error', (err) => {
        console.log('Server Error', + err);
    });
});
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebSocket Client</title>
  <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script type="text/javascript">
    var output;
    var userName;
    var sendData;
    function makeDom(msg){
      var p = document.createElement('p');
      p.innerHTML = msg;
      p.style.wordWrap = 'block-word';
      output.appendChild(p);
    } 
    function init() {
      var ws = new WebSocket('ws://localhost:3000');     
      // open 
      ws.addEventListener('open', function(evt){
        userName = 'USER' + Math.floor(Math.random() * 100);
        sendData = {event: 'open', data: userName};
        ws.send(JSON.stringify(sendData)); // JavaScript 객체 => JSON(문자열)로 변환
      }); 
      ws.addEventListener('close', function(evt){
        console.log('Client 정상 종료');
      });
      ws.addEventListener('error', function(evt){
      });
      ws.addEventListener('message', function(evt){
          console.log('client Message', evt);
          
          var serverData = JSON.parse(evt.data);
          var dom; 
          switch(serverData.event){
            case 'open':  // {event: 'open', data: 'USER22'}
              dom = '<span style="color:orange;">' + serverData.data + '님이 방문하셨습니다.</span>';
              makeDom(dom);
              break;
            case 'close':  // {event: 'close', data: 'USER22'}
              dom = '<span style="color:orange;">' + serverData.data + '님이 나가셨습니다.</span>';
              makeDom(dom);
              break;
            case 'chat':  // {event: 'chat', data: {userName: 'USER22', msg:'Some Msg'}}
              if(serverData.data.userName === userName){ // 내가쓴글
                dom = '<span style="color:green;">' + serverData.data.userName + ': ' + serverData.data.msg + '</span>';
              }
              else{
                dom = '<span style="color:gray;">' + serverData.data.userName + ': ' + serverData.data.msg + '</span>';
              }
              makeDom(dom);
              break;
          }
      }); 
      output = document.getElementById('output');
      document.getElementById('sendBtn').addEventListener('click', function(){
          var field = document.getElementById('data');
          sendData = {event: 'chat', data:field.value};
          ws.send(JSON.stringify(sendData));
          field.value='';
          field.focus();
      });      
      document.getElementById('closeBtn').addEventListener('click', function(){
        sendData = {event: 'close', data: userName}
        ws.send( JSON.stringify(sendData));
        ws.close(1000, '정상 종료'); 
      });
    }
    
    window.addEventListener('load', init);
  </script>
</head>
<body>
  <div class="card-body">
    <h3>WebSocket</h3>
    <hr>
    <div id="output"></div>
    <div class="input-group">
      <input type="text" class="form-control" id="data">
      <div class="input-group-append">
        <button class="btn btn-danger" id="sendBtn">SEND</button>
      </div>
    </div>
    <br>
    <button class="btn btn-primary" id="closeBtn">종료</button>
  </div>
</body>
</html>



// ws04_server.js
// node용 WebSocket lib가 필요
// 설치
// npm i ws
// ctrl + `
// express
// npm i express
// websocket은 기본 서버 기준
const http = require('http');           // 기본 웹 서버
const express = require('express')      // express 서버
const app = express();                  // express 서버 실행
const server = http.createServer(app);  //  기본 웹 서버에서 express 이용
// 라이브러리 불러오기
const WebSocket = require('ws');
// websocket 서버
const wss = new WebSocket.Server({server}); // server port를 그대로 사용
// 서버 시작
server.listen(3000, () => {
    console.log('Server Started on port 3000');
});
// 페이지 출력
app.get('/ws', (req, res) => {
    res.sendFile(__dirname + '/ws04_client.html');
})
// Node에서는 이벤트를 on으로 처리\
wss.on('connection', function(ws){
    // 모든 처리는 이 connection 내부에서 처리한다. 
    // 연결되면 open이벤트를 client에 전달한다.
    console.log('Server Connected...');    
    ws.send('Hello World');     // client 의 message event가 받게 된다.
    // client에서 넘어온 메시지를 받아 편집(여기서는 안함)해서 클라이언트에 전달
    // client data 형식 => {event: 'open', data: 'Hello World'}
    ws.on('message', (evt) => {
        var clientData = JSON.parse(evt);   // JSON => JavaScript 객체
        console.log('Serve Messsage', clientData); // clg
        //ws.send('Server=> ' + evt);
        
        var sendData;
        switch(clientData.event){
            case 'open': // {event: 'open', data: 'USER22'}
                    ws.userName = clientData.data;
                    sendData = {event: 'open', data: ws.userName};
                    //ws.send( JSON.stringify(sendData));
                    wss.clients.forEach( (client) => {
                        client.send( JSON.stringify(sendData));
                    })
                break;
            case 'close':  // {event: 'close', data: 'USER22'}
                //ws.userName = clientData.data;
                sendData = {event: 'close', data: ws.userName};
                //ws.send( JSON.stringify(sendData));                
                wss.clients.forEach( (client) => {
                    client.send( JSON.stringify(sendData));
                })
                break;
            case 'chat':  // {event: 'chat', data: 'Some Message'}
                //ws.userName = clientData.data;
                sendData = {event: 'chat', data: {userName: ws.userName, msg: clientData.data}};
                //ws.send( JSON.stringify(sendData));               
                wss.clients.forEach( (client) => {
                    client.send( JSON.stringify(sendData));
                })          
                break;
        }
    });
    ws.on('close', (code, msg) => {
        console.log(`WebSocket Closed Code: ${code}, Msg: ${msg}`);
    });
    ws.on('error', (err) => {
        console.log('Server Error', + err);
    });
});
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebSocket Client</title>
  <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
  <script type="text/javascript">
    var output;
    var userName;
    var sendData;
    function makeDom(msg){
      var p = document.createElement('p');
      p.innerHTML = msg;
      p.style.wordWrap = 'block-word';
      output.appendChild(p);
    } 
    function init() {
      var ws = new WebSocket('ws://localhost:3000');     
      // open 
      ws.addEventListener('open', function(evt){
        userName = 'USER' + Math.floor(Math.random() * 100);
        sendData = {event: 'open', data: userName};
        ws.send(JSON.stringify(sendData)); // JavaScript 객체 => JSON(문자열)로 변환
      }); 
      ws.addEventListener('close', function(evt){
        console.log('Client 정상 종료');
      }); 
      ws.addEventListener('error', function(evt){
      }); 
      ws.addEventListener('message', function(evt){
          console.log('client Message', evt);
          var serverData = JSON.parse(evt.data);
          var dom;
          switch(serverData.event){
            case 'open':  // {event: 'open', data: 'USER22'}
              dom = '<span style="color:orange;">' + serverData.data + '님이 방문하셨습니다.</span>';
              makeDom(dom);
              break;
            case 'close':  // {event: 'close', data: 'USER22'}
              dom = '<span style="color:orange;">' + serverData.data + '님이 나가셨습니다.</span>';
              makeDom(dom);
              break;
            case 'chat':  // {event: 'chat', data: {userName: 'USER22', msg:'Some Msg'}}
              if(serverData.data.userName === userName){ // 내가쓴글
                dom = '<span style="color:green;">' + serverData.data.userName + ': ' + serverData.data.msg + '</span>';
              }
              else{
                dom = '<span style="color:gray;">' + serverData.data.userName + ': ' + serverData.data.msg + '</span>';
              } 
              makeDom(dom);
              break;
          }
      }); 
      output = document.getElementById('output'); 
      document.getElementById('sendBtn').addEventListener('click', function(){
          var field = document.getElementById('data');
          sendData = {event: 'chat', data:field.value};
          ws.send(JSON.stringify(sendData)); 
          field.value='';
          field.focus();
      });      
      document.getElementById('closeBtn').addEventListener('click', function(){
        sendData = {event: 'close', data: userName}
        ws.send( JSON.stringify(sendData));
        ws.close(1000, '정상 종료'); 
      });
    }
    window.addEventListener('load', init);
  </script>
</head>
<body>
  <div class="card-body">
    <h3>WebSocket</h3>
    <hr>
    <div id="output"></div>
    <div class="input-group">
      <input type="text" class="form-control" id="data">
      <div class="input-group-append">
        <button class="btn btn-danger" id="sendBtn">SEND</button>
      </div>
    </div>
    <br>
    <button class="btn btn-primary" id="closeBtn">종료</button>
  </div>
</body>
</html>