본문 바로가기
소프트웨어/자바스크립트

[자바스크립트] Node.js - 웹서버에 Websocket 통신 추가하기

by 만들오 2021. 1. 23.

안녕하세요? 어제는 Node.js와 express 모듈을 이용해 웹서버를 구현해보았습니다.

 

오늘은 웹서버-Client간의 통신 중 가장 빠르고 대표적인 Websocket통신을 구현하겠습니다.

 

기존 웹서버를 만드는건 https://ohcoach.tistory.com/14 를 참고해 주세요.

 

1. 프로젝트에 express-ws 추가하기

npm install express-ws

2. index.js에 express-ws 모듈 사용하기

//index.js
let express = require("express");
let app = express();
let expressWS = require("express-ws")(app); //웹소켓모듈 추가

app.use(express.static('public'));
app.get("/", function(req, res){
    res.sendfile("public/index.html");
});

app.ws("/", function(ws, req){ //웹소켓 연결 및 신호처리
    ws.on("message", function(msg){
        console.log(msg);
    });
});

app.listen(3000, function(){
    console.log("App is running on port 3000");
});

기존 코드에 몇줄이 추가되었습니다. 웹소켓이 연결된 상태에서 메시지가 도착하면 console.log(msg)를 통해 그대로 콘솔창에 로그를 남깁니다.

 

3. public/index.html 파일

<!DOCTYPE html>
<html>

<body>
  <canvas id="joy" style="border:5px dashed #BDBDBD"></canvas>
  <script>
    let ws = new WebSocket("ws://localhost:3000"); //웹소켓 생성
    ws.onopen = function(){
      ws.send("Websocket is ready!");
    }
    var joy = document.getElementById("joy");
    joy.width = 200;
    joy.height = 200;
    joy.addEventListener("touchstart", down);
    joy.addEventListener("touchmove", move);
    joy.addEventListener("touchend", up);
    joy.addEventListener("mousedown", down);
    joy.addEventListener("mousemove", move);
    joy.addEventListener("mouseup", up);
    joy.addEventListener("mouseleave", up);
    var ctx = joy.getContext("2d");
    ctx.lineWidth = 10;
    clearBackground();
    drawCircle(100, 100, 50, "rgb(255,000,051)");
    var startX, startY, moveX, moveY;
    var joyPos = joy.getBoundingClientRect();
    var onTouch = false;
    function down(event) {
      try {
        startX = Math.round(event.touches[0].clientX - joyPos.left);
        startY = Math.round(event.touches[0].clientY - joyPos.top);
      } catch{
        startX = Math.round(event.clientX - joyPos.left);
        startY = Math.round(event.clientY - joyPos.top);
      }
      onTouch = true;
    }

    var moveMax = 40;
    var msgPrev = "s";
    var msg = "s";
    function move(event) {
      if (onTouch) {
        try {
          moveX = Math.round(event.touches[0].clientX - joyPos.left) - startX;
          moveY = Math.round(event.touches[0].clientY - joyPos.top) - startY;
        } catch{
          moveX = Math.round(event.clientX - joyPos.left) - startX;
          moveY = Math.round(event.clientY - joyPos.top) - startY;
        }

        if (moveX > moveMax) moveX = moveMax;
        else if (moveX < -moveMax) moveX = -moveMax;
        if (moveY > moveMax) moveY = moveMax;
        else if (moveY < -moveMax) moveY = -moveMax;

        clearBackground();
        drawCircle(100 + moveX, 100 + moveY, 50, "rgb(255,000,051)");

        if (moveX >= 35) msg = "d";
        else if (moveX <= -35) msg = "a";
        else if (moveY <= -35) msg = "w";
        else if (moveY >= 35) msg = "x";

        if (msg != msgPrev) {
          send(msg);
          msgPrev = msg;
        }
      }

    }

    function up() {
      clearBackground();
      drawCircle(100, 100, 50, "rgb(255,000,051)");
      msg = "s";
      msgPrev = "s";
      onTouch = false;
      send(msg);
    }

    function send(msg) {
      console.log(msg);
      ws.send(msg);
    }

    function clearBackground() {
      ctx.clearRect(0, 0, joy.width, joy.height);
      ctx.beginPath();
      ctx.strokeStyle = "rgb(153,000,051)";
      ctx.arc(100, 100, 90, 0, 2 * Math.PI);
      ctx.stroke();
    }

    function drawCircle(x, y, r, c) {
      ctx.beginPath();
      ctx.fillStyle = c;
      ctx.arc(x, y, r, 0, 2 * Math.PI);
      ctx.fill();
    }
  </script>
</body>

</html>

기존 https://ohcoach.tistory.com/6?category=810255 코드에서 마찬가지로 신호부분만 수정을 했습니다.

let ws = new WebSocket("ws://localhost:3000");
    ws.onopen = function(){
      ws.send("Websocket is ready!");
    }

위와 같이 웹소켓을 불러오고 지정된 포트로 연결을 합니다. 연결이 성공하면 Websocket is ready! 라는 문구를 서버로 보냅니다. 그럼 서버에서는 console.log를 통해 메시지가 나오겠죠?

function send(msg) {
      console.log(msg);
      ws.send(msg);
    }

위 코드는 기존 console.log에 추가로 ws.send(msg)를 추가했습니다. 서버로 메시지를 보냅니다.

 

예제는 RC카 조작을 위한 간단한 문구만 보냈지만, <canvas>태그의 이미지를 다음과 같이 dataURL 형식으로 전송할 수도 있습니다.

let rawData = canvas.toDataURL("image/jpeg", 0.5);

* 이 글은 티스토리 카카오계정 연동정책으로 인해 이전 블로그(오코취) 글을 옮겨왔습니다.

[].

728x90

댓글