728x90

#2.0 SocketIO vs WebSockets

실시간 기능을 지원하는 framework는 SocketIO이다. 이는 나온지 오래되었으며 매우 안정적이다.

 

SocketIO기능 : 실시간, 양방향, event 기반 comm. (=> Websocet 과 같은 기능.)

그러나 SocketIO는 websocket 을 실행하는 것이 아님. 

websocket은 SocketIO 가 제공하는 기능 중 하나임. 

그저 SocketIO는 가끔 websocket을 이용해서 websocket 의 기능을 제공하는 framework임

 

SocketIO는 HTTP long polling 을 사용하여 wifi 연결이 잠시 끊겨도 재연결을 시도한다.

 

그럼 SocketIO 기능을 사용해보고 이를 websocket 과 비교해보자

 

#2.1 Installing SocketIO 

먼저 SocketIO를 설치한다.

npm i socket.io

 

그리고 SocketIO 를 import 하고 wsServer 변수를 선언해준다.

import http from "http";
import SocketIO from "socket.io"
import WebSocket from "ws";
import express from "express";

const app = express();

//set the view
app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public")); //user가 public 으로 이동하면 __dirname+/public 폴더를 보여주는 것. 
app.get("/", (req, res) => res.render("home"));//render 
app.get("/*", (req, res) => res.redirect("/"));

const handleListen = () => console.log('Listening on http://localhost:3000');
//app.listen(3000, handleListen);

//http의 서버
const httpServer = http.createServer(app); //app은 requestListener 의 경로. express application으로부터 서버 생성. 
const wsServer  = SocketIO(httpServer);



//websocket 서버
//const wss = new WebSocket.Server({ httpServer });


// function handleConnection(socket) {
//     console.log(socket)
// }

// const sockets = [];

// wss.on("connection", (socket) => {
//     sockets.push(socket);
//     socket["nickname"] = "Anon";    //처음엔 익명으로 설정 
//     console.log("Connected to Browser ✅");
//     socket.on("close", () => {
//         console.log("Disconnected from the Browser ❌");
//     });
//     socket.on("message", (msg) => { 
//         const message = JSON.parse(msg);        //string -> Object
//         //console.log(message, message.toString('utf-8'));
//         switch(message.type){
//             case "new_message" :
//                 //sockets.forEach((aSocket) => aSocket.send(message.payload.toString('utf-8'))); //채팅 메세지만 출력하기 위해 이것만 브라우저에 보냄 
//                 sockets.forEach((aSocket) => aSocket.send(`${socket.nickname}: ${message.payload}`)); //누가 보냈는지, 뭘 보냈는지 
//             case "nickname" :
//                 //console.log(message.payload.toString('utf-8'));     
//                 socket["nickname"] = message.payload;
//         }
//     });
    
// });

httpServer.listen(3000, handleListen);

여기까지 설치를 했으면 SocketIO는 url 을 준다.

=> http://localhost:3000/socket.io/socket.io.js

url 로 들어가면 아래와 같은 내용이 나온다.

이제 frontend 에도 SocketIO 를 설치해주자. (websocket에서는 따로 설치 없이 브라우저가 주는 websocket API를 쓰면 됐었음)

이제 기존 코드를 삭제하고 다시 시작해보자. 

그 전에 아카이빙을 하자.


home.pug

doctype html
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(http-equiv="X-UA-Compatible", content="IE=edge")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        title Noom
        link(rel="stylesheet", href="https://unpkg.com/mvp.css")
    body 
        header
            h1 Noom 
        main 
            form#nick
                input(type="text", placeholder="choose a nickname", required) 
                button Save
            ul
            form#message
                input(type="text", placeholder="write a msg", required) 
                button Send
        script(src="/public/js/app.js")

app.js (frontend)

const messageList = document.querySelector("ul");
const nickForm = document.querySelector("#nick");
const messageForm = document.querySelector("#message");
const socket = new WebSocket(`ws://${window.location.host}`);

function makeMessage(type, payload){
    const msg = {type, payload};
    return JSON.stringify(msg); //string으로 바꿔서 리턴
}

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

socket.addEventListener("message", (message)=>{
    //console.log("New message", message.data);
    const li = document.createElement("li");
    li.innerText = message.data;
    messageList.append(li);
});

socket.addEventListener("close", ()=>{
    console.log("Disconnected from Server ❌");
});

function handleSubmit(event){
    event.preventDefault();
    const input = messageForm.querySelector("input");
    socket.send(makeMessage("new_message", input.value));   //front -> back 전송
    const li = document.createElement("li");
    li.innerText = `You: ${input.value}`;
    messageList.append(li);
    input.value = "";           //초기화
    //console.log(input.value);
}

function handleNickSubmit(event){
    event.preventDefault();
    const input = nickForm.querySelector("input");
    //socket.send(input.value);   //front -> back 전송
    socket.send(makeMessage("nickname", input.value));   //front -> back 전송
    input.value = "";           //초기화
}
messageForm.addEventListener("submit", handleSubmit);
nickForm.addEventListener("submit", handleNickSubmit);


// setTimeout( () => {
//     socket.send("Hello from the browser!");
// }, 10000);//10sec

server.js (backend)

import http from "http";
import SocketIO from "socket.io"
import WebSocket from "ws";
import express from "express";

const app = express();

//set the view
app.set("view engine", "pug");
app.set("views", __dirname + "/views");
app.use("/public", express.static(__dirname + "/public")); //user가 public 으로 이동하면 __dirname+/public 폴더를 보여주는 것. 
app.get("/", (req, res) => res.render("home"));//render 
app.get("/*", (req, res) => res.redirect("/"));

const handleListen = () => console.log('Listening on http://localhost:3000');
//app.listen(3000, handleListen);

//http의 서버
const httpServer = http.createServer(app); //app은 requestListener 의 경로. express application으로부터 서버 생성. 
const wsServer  = SocketIO(httpServer);



//websocket 서버
//const wss = new WebSocket.Server({ httpServer });


// function handleConnection(socket) {
//     console.log(socket)
// }

// const sockets = [];

// wss.on("connection", (socket) => {
//     sockets.push(socket);
//     socket["nickname"] = "Anon";    //처음엔 익명으로 설정 
//     console.log("Connected to Browser ✅");
//     socket.on("close", () => {
//         console.log("Disconnected from the Browser ❌");
//     });
//     socket.on("message", (msg) => { 
//         const message = JSON.parse(msg);        //string -> Object
//         //console.log(message, message.toString('utf-8'));
//         switch(message.type){
//             case "new_message" :
//                 //sockets.forEach((aSocket) => aSocket.send(message.payload.toString('utf-8'))); //채팅 메세지만 출력하기 위해 이것만 브라우저에 보냄 
//                 sockets.forEach((aSocket) => aSocket.send(`${socket.nickname}: ${message.payload}`)); //누가 보냈는지, 뭘 보냈는지 
//             case "nickname" :
//                 //console.log(message.payload.toString('utf-8'));     
//                 socket["nickname"] = message.payload;
//         }
//     });
    
// });

httpServer.listen(3000, handleListen);

 

 


 

html 파일을 수정한다.  (line 13)

doctype html
html(lang="en")
    head
        meta(charset="UTF-8")
        meta(http-equiv="X-UA-Compatible", content="IE=edge")
        meta(name="viewport", content="width=device-width, initial-scale=1.0")
        title Noom
        link(rel="stylesheet", href="https://unpkg.com/mvp.css")
    body 
        header
            h1 Noom 
        main 
        script(src="/socket.io/socket.io.js")    
        script(src="/public/js/app.js")

 

io : 자동으로 backend socket.io와 연결해주는 function 이다. 자동으로 socket.io를 실행하고 있는 서버를 찾을 것이다. 

설치가 되면 브라우저에서 io 함수를 실행할 수 있고 

실행한 내용은 backend 에 찍힌다. 

 

 

728x90

+ Recent posts