본문 바로가기
Web Service/NodeJS

[ZOOM 클론 코딩] #2. WebSockets

by junnykim 2022. 8. 4.

~1.5까지의 강의

 

먼저, HTTP와 WebSocket의 차이점을 알아보자.

HTTP VS WebSocket

둘다 protocol이기는 하다. 즉, 모든 server들이 작동하는 방식이다.

 

 

HTTP

user가 request를 보내면 서버는 response를 준다. 즉, server가 반응하는 것이다.

(앞에서 user가 뭘 보내면 반응하도록 server.js에서 해보았다.)

인터넷 전체가 http를 기반으로 만들어져있다.

 

기억해야할 것인 statelss이다. 즉,백엔드가 user를 기억하지 못한다는 것이다.

request&response 과정 뒤에 백엔드는 user를 잃어버린다. 즉, response만 주면 끝나는 것이다.

server로 메세지를 보내고 싶으면 내가 누구인지 알려주는 쿠키를 server에 보내야한다.

그럼 server가 일치하는 것을 response로 준다.

 

서버는 오직 request를 받을 때만 response을 해준다. 즉, 브라우저가 request를 보내면 response을 해주는 것이다.

근데 real-time으로 하지 않는다.

왜냐면 requset를 보내야하고 기다려야 하기 때문이다.

server는 갑자기 불쑥 대화를 걸 수 없다.

이것이 http protocol이다. 모든 인터넷이 중심이다.

 

 

WebSocket

이것을 사용해 연결하고 싶고, server가 지원하면 Web Socket Server이다.

어떻게 작동할까?

WebSocket이 연결이 일어나면,  server가 받거나 거절한다.

이런게 성립되면 연결은 계속 성립한다.

브라우저와  server가 손을 맞잡은 것처럼 서로 커뮤니케이션을 하는 것이다.

말그대로 연결되는 것이다.

연결되어 있어서  server는 기억할 필요가 없다.

 

그리고, 원한다면  server가 user에게 메시지를 보낼수 있다.

 server는 request를 보내지 않아도 된다.

이것은 양방향의 연결이기 때문이다.

 server는 user에게 메시지를 보낼 수 있고 user도  server에게 메시지를 보낼 수 있다.

이것은 연결중일 때만 발생한다.

브라우저는  server에게 언제나 보낼수있다. server도 마찬가지이다.

즉, 한 번 연결되고 나면 끊임없이 연결되어 있는 것이다.

그리고 언어에 국한되어 있지 않다.

 


node.js로 서버를 만들건데 ws라는 package의 도움을 받을 것이다.

즉, protocol 관점에서 ws와 http를 사용하는 것이다.

protocol은 어딘가에 있는 방에서 만나고 어떻게 일들이 진행될지를 결정한다.

즉, 어떻게 모든 것이 돌아가야할지 결정하는 것이다.

이 규칙을 가지고 규칙이 따르는 코드를 만들어서 실행한다.

 

node.js에서는 WebSocket의 핵심인 ws이다.

ws는 WebSocket의 핵심인 implement일 뿐이다.

 

설치 ->  npm i ws

그리고 서버를 만들건데 express서버를 놓고 함께 합칠것이다.

espress는 http를 다루고 있지만, 이제 ws(websocket)을 다룰것이다.

 

2개를 합칠것이다. express로 같은 서버에 ws기능을 설치할 것이다. 

그런데 이것을 위해서 무언가가 바뀌어야 한다.

 

appliction을 시작하는 방법을 바꿔보자.

node.js에 내정되어있는 http package를 사용해보자.

1. 먼저 import를 해준다.

import http from "http";

 

2. createServer를 해준다.

const server = http.createServer(app);

그러면 request경로가 있어야한다.

 

epxres applicaion으로 부터 서버를 만들어보자.

3. ws를 import한다.

import WebSocket forom "ws";

 

4. 이제 웹소캣 서버를 만들것이다.

const wss = new WebSocket.Server({server});

 

크게 달라진 것은 없지만 큰 변화이다. 

http 서버에 접근한 후, http 서버위에 WebSocket서버를 만들수 있도록 한 것이다.

이유는 우리의 서버를 만들고, http서버위에 ws서버를 만들기 위함이다.

 

http 서버가 있으면 그 위에서 ws 서버를 마들 수 있다.

그래서 2개의 프로토콜 같은 포트를 공유하는 것이다

우리의 서버는 http 프로토콜과 ws 커넥션을 지원한다.

 

server.js

더보기
import http from "http";
import WebSocket from "ws";
import express from "express";

const app = express();

app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));

const handleListen = () => console.log(`Listening on http://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

server.listen(3000, handleListen);

 


 

이제 ws를 사용해서 백과 프론트 사이에 메시지를 주고받아보자.

프론트 브라우저에서 implement를 가지고 있다.

WebSocket을 이용해 백앤드와 연결하고 싶다면  js가 해줄것이다.

아무것도 설치할 필요없이 브라우저에서 지원을 해줄것이다.

 

우리는 http가 어떻게 생겼는지 안다.

url을 선언 후, 유저가 url에 가면 req와 res를 받고, response를 보낸다.

 

WebSocket은 http와 완전히 같지는 않지만, WebSocket에서는 프론트에서 한 것과 비슷하다.

프론트(app.js)를 보면 버튼을 만들고 리스너를 정할 수 있다.

이벤트가 발동될 때 사용할 함수를 만들면된다.

 

js는 함수를 가지고 호출하고, 정보를 줄 것이다.

이것이 작동할 것이라는 것도 않다.

function fn(event){}

 

js는 이벤트의 정보와 함수를 호출할 것이다.

어떤 일이 발생했는지데 대한 정보도 안다.

wss.on을 하고 함수도 받는다. 함수는 발생할 때 호출되는 것이다. 즉, 클릭될 때 호출되는 것이다.

 

그리고 함수를 넣어주어야 한다.

handleConnection을 넣고 함수를 넣어주면 된다.

socket은 연결된 어떤 사람인 것이다. socket을 이용하면 정보를주고 받을 수 있다.

]

on method에서는 이벤트가 발동하는걸 기다린다.

커넥션이 이루어지면 작동한다.

on method는 백엔드에 연결된 사람의 정보를 제공해준다.

그것이 socket에서 오는 것이다.

 

WebSocket을 이용해서 새로운 핸들러를 가지고 오는 것이다.

프론트에 가서 백엔드랑 연결해달라고 하자.

 

우리는 같은 url이라는 것을 안다.

브라우저 스스로가 가지고 오게 해야한다.

 

여러가지 다양한 웹소켓이 출력된다.

 

이제 접근할 수 있다. 소켓이 실시간으로 소통할 수 있다.

프론트에서 백으로 메세지를 보낼 수 있을 것이다.

그리고 백엔드로 부터 메시지를 받을 수 잇을 것이다.

 

server.js

더보기
import http from "http";
import WebSocket from "ws";
import express from "express";

const app = express();

app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));

const handleListen = () => console.log(`Listening on http://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });


function handleConnection(socket) {
    console.log(socket);
  }
  wss.on("connection", handleConnection);
  
server.listen(3000, handleListen);

app.js

더보기
const socket = new WebSocket(`ws://${window.location.host}`);

하나의 함수에 기능을 넣어보도록 하자.

server.js

wss.on("connection", (socket) => {
    console.log("Connected to Browser ✅");
    socket.on("close", () => console.log("Disconnected from the Browser ❌"));
    socket.on("message", (message) => {
      console.log(message);
    });
    socket.send("hello!!!");
  });

connetction안에 같은 역할을 하는 익명 함수를 만들어보자. 그러면 socket이 지금 어떤 상태인지 알기 쉽다.

connetction이 생기면 socket이 발생하기 때문이다.

연결을해서 socket을 알 수 있다.

 

app.js

더보기
socket.addEventListener("open", () => {
    console.log("Connected to Server ✅");
  });
  
  socket.addEventListener("message", (message) => {
    console.log("New message: ", message.data);
  });
  
  socket.addEventListener("close", () => {
    console.log("Disconnected from Server ❌");
  });
  
  setTimeout(() => {
    socket.send("hello from the browser!");
  }, 10000);

그 후 브라우저에서 message를 보내보자.

socket에 있는 메소드를 사용한다.

socket으로 직접적인 연결을 해준다.

우리가 해야할 것은 message 받기이고 이벤트이다.

연결이 생겼을 때 socket으로 즉시 메시지를 보낸것이다.

 

연결이 끊기면 서버에 보내고, 서버가 오프라인이되면 브라우저에 알려준다.

즉시 실행되지 않게 하기위해서 setTimeout을 사용한다.

프론트에서 백엔드로 연결을 만들어주고 백은 연결을 기다리면된다.

 

브라우저에서 확인 가능
서버에서 온 메시지

버퍼가 발생할 경우 toString()을 해주면 됩니다.

 

app.js

더보기
const socket = new WebSocket(`ws://${window.location.host}`);

socket.addEventListener("open", () => {
    console.log("Connected to Server ✅");
  });
  
  socket.addEventListener("message", (message) => {
    console.log("New message: ", message.data);
  });
  
  socket.addEventListener("close", () => {
    console.log("Disconnected from Server ❌");
  });
  
  setTimeout(() => {
    socket.send("hello from the browser!");
  }, 10000);

server.js

더보기
import http from "http";
import WebSocket from "ws";
import express from "express";

const app = express();

app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));

const handleListen = () => console.log(`Listening on http://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });


wss.on("connection", (socket) => {
    console.log("Connected to Browser ✅");
    socket.on("close", () => console.log("Disconnected from the Browser ❌"));
    socket.on("message", (message) => {
      /*console.log(message);*/
      /*버퍼가 생긴다면*/
      console.log(message.toString());
    });
    socket.send("hello!!!");
  });

server.listen(3000, handleListen);

server.js

import http from "http";
import WebSocket from "ws";
import express from "express";

const app = express();

app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public"));
app.get("/", (_, res) => res.render("home"));
app.get("/*", (_, res) => res.redirect("/"));

const handleListen = () => console.log(`Listening on http://localhost:3000`);
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

function onSocketClose() {
    console.log("Disconnected from the Browser ❌");
  }
  
  function onSocketMessage(message) {
    console.log(message);
  }
  

wss.on("connection", (socket) => {
    console.log("Connected to Browser ✅");
    socket.on("close", onSocketClose);
    socket.on("message", onSocketMessage);
    socket.send("hello!!!");
  });

server.listen(3000, handleListen);

 

백엔드틑 socket 서버를 만들었다.

이벤트가 발생하면 반응을 해야하니까 연결하기 위해 필수로 해야하는 것이다.

우리는 이벤트를 listen해주어야 한다.

페이지에 있는 버튼과 같다.

 

app.js

const socket = new WebSocket(`ws://${window.location.host}`);

function handleOpen() {
    console.log("Connected to Server ✅");
    }
  
    socket.addEventListener("open", handleOpen);

  socket.addEventListener("message", (message) => {
    console.log("New message: ", message.data);
  });
  
  socket.addEventListener("close", () => {
    console.log("Disconnected from Server ❌");
  });
  
  setTimeout(() => {
    socket.send("hello from the browser!");
  }, 10000);

커넥션이 생기면 socket에서 누가 연결했는지 알 수 있다.

socket에서 이벤트를 연결시킬 수 있다.

우리는 특정 socket에서 메시지를 기다리고 있다.

 

이것이 특정 socket이고 event lister를 등록했다.

그리고 서버 전체를 위한 것이다.

socket에서 메시지를 받았을 때 발생할 것이다.

새로운 브라우저가 서버에 들어오면 같은 코드를 실행시켜줄 것이다.

우리는 EventLister를 추가해주었다.

그리고 익명함수( () 이런거 )를 사용했다.

싫으면 잘라서 위에 새로운 함수를 만들면 된다.

그리고 원하는 내용을 console로 찍으면 된다.

 

즉, 그냥 많은 이벤트가 있는 것이다.

프론트랑 백 둘다에 생기는 것이다.

'Web Service > NodeJS' 카테고리의 다른 글

[ZOOM 클론 코딩] #4. SocketIO  (1) 2022.08.31
[ZOOM 클론 코딩] #3. Chat & Nicknames  (4) 2022.08.24
[ZOOM 클론 코딩] #1. Set up  (0) 2022.07.30

댓글