본문 바로가기

블록체인_9기/💚 Node.js

37강_230524_Node.js(web socket, socket.io)

728x90

 

 

 

 


Web Socket

  • HTML5에 새로 추가된 스펙으로 실시간 양방향 데이터 전송을 위한 기술이다.
  • 웹소켓은  ' WS ' 라는 프로토콜을 사용하므로 브라우저와 서버가 해당 프로토콜을 지원한다면 사용이 가능하다.
    • 최신 브라우저는 대부분 웹 소켓을 지원한다.
    • 통신 시 지정되는 URL은 ' http:// ~ ' 가 아닌 ' ws:// ~ '와 같은 형식으로 저장된다.
  • web socket이 나오기 이전에는 HTTP 기술을 이용해 실시간 데이터 전송을 구현하였었다.
    • 그 중 한 가지 방법이 폴링(Polling)이다. 
    • HTTP가 클라이언트에서 서버로 향하는 단방향 통신으로 주기적으로 서버에 업데이트 확인 요청을 보내고 업데이트 내용이 있다면 그 내용을 가져오는 단순한 방식이었다.
    • 웹 소켓은 폴링 방식에 비해 성능이 매우 개선된 방식이다.
  • web socket의 경우, 처음에 웹 소켓 연결이 이루어지고 나면 그 다음부터는 계속 연결된 상태로 있어 따로 업데이트가 있는지 요청을 보낼 필요가 없다.
    • 업데이트를 할 내용이 있다면 서버에서 바로 클라이언트에게 알린다.
    • 처음에 웹 소켓 연결 시 헤더의 값이 전송되기 때문에 오버헤드가 일어나지 않는다.
  • HTTP 프로토콜과 포트를 공유할 수 있으므로 다른 포트에 연결할 필요가 없다. 

WebSocket이 필요한 경우

  • 실시간 양방향 데이터 통신이 필요한 경우
  • 많은 수의 동시 접속자를 수용해야 하는 경우
  • 브라우저에서 TCP 기반의 통신으로 확장해야 하는 경우
  • 개발자에게 사용하지 쉬운 API가 필요한 경우
  • 클라우드 환경이나 웹을 넘어 SOA(service Oriented Architecture)로 확장하는 경우
  • 예) 실시간 채킹을 구현하거나, 가상화폐 거래소 등

WebSocket 서버의 종류

  • pywebsocket(apache)
  • phpwebsocket(php)
  • jWebSocket(java,javascript)
  • web-socket-ruby(ruby)
  • Socket.IO(node.js)

 

 

 

 


Socket.io

  • Web socket은 HTML5의 기술이기 때문에 오래된 버전의 웹 브라우저는 웹 소켓을 지원하지 않는다.
  • Socket.io는 웹 소켓을 편리하게 사용할 수 있도록 도와주는 라이브러리이다.
  • node.js를 기반으로 만들어진 기술로, 거의 모든 웹 브라우저와 모바일 장치를 지원하는 웹 어플리케이션 지원 라이브러리이다.
  • 페이지에서 댓글을 달았다고 가정했을 때 페이지를 새로고침해야 글이 다시 보이는 것을 웹 소켓으로 양방향 통신으로 실시간으로 글이 보이도록 처리할 수 있다.

socket 메세지 수신

// 접속된 모든 클라이언트에게 메시지를 전송한다
io.emit('event_name', msg);

// 메시지를 전송한 클라이언트에게만 메시지를 전송한다
socket.emit('event_name', msg);

// 메시지를 전송한 클라이언트를 제외한 모든 클라이언트에게 메시지를 전송한다
socket.broadcast.emit('event_name', msg);

// 특정 클라이언트에게만 메시지를 전송한다
io.to(id).emit('event_name', data);

socket 메세지 송신

// 클라이언트와 소켓IO 연결됬는지 안됬는지 이벤트 실행. (채팅방에 누가 입장하였습니다/퇴장하였습니다 )
io.on('connection/disconnection', (socket) => {
});

// 클라이언트에서 지정한 이벤트가 emit되면 수신 발생
socket.on('event_name', (data) => {
});

 

 

 

 


Socket.io를 이용하여 특정 사용자에게 메시지 전송

#. 폴더의 경로는 다음과 같다.

  • 여기서 app2.js와 main2.ejs는 다음의 채팅방 제작에 사용되는 파일이다.

1. app.js_웹 서버를 열기 위한 기본 세팅 설정

  • 사용할 모듈을 내려받고 불러온다.
// 사용할 모듈을 터미널에서 다운받는다.
// npm init -y
// npm i express ejs socket.io

const express = require("express");
const path = require("path");
const socketIo = require("socket.io");
  • 서버 인스턴스를 생성한다.
const app = express();
  • view엔진 경로를 설정한다.
app.set("views", path.join(__dirname,"page"));
app.set("view engine", "ejs");
  • 서버를 대기 상태로 변경한 후 서버 객체를 소켓의 매개변수로 전달한다.
const server = app.listen(6767, ()=>{
    console.log("서버열림")
})

const io = socketIo(server);

2. app.js_페이지 접속 시 " connection "이벤트가 실행되고, 페이지를 나가면 " disconnect " 이벤트가 실행된다. 

  • connection : 유저가 접속 시 실행되는 이벤트이다. 접속한 클라이언트의 socket이 매개변수로 들어온다.
  • UserId: 전역공간에 접속한 유저의 아이디를 담을 빈 배열을 선언한다.
    • 클라이언트의 socket.id의 정보를 배열로 push하여 접속한 유저의 아이디를 추가한다.
    • 유저가 접속을 종료하면 filte메서드를 이용하여 접속한 유저의 정보를 담고 있는 UserId에서 종료한 아이디를 담고있는 socket.id를 제외한 새로운 배열을 담는다.
let userId = [];

// 소켓들에게 이벤트를 등록한다.
io.sockets.on("connection", (socket)=>{
    // 접속한 클라이언트의 socket이 매개변수로 들어온다.
    // 유저 한 명이 접속했다는 얘기이다.
    console.log("유저 접속")
    // 유저 아이디를 배열에 담아놓는다.
    userId.push(socket.id);

    // 클라이언트 측에서 이벤트가 푸쉬되면 실행시킬 이벤트
    socket.on("hi", (data)=>{
        // 자기 자신에게 이벤트 푸쉬
        console.log(data, "이벤트를 클라이언트에서 보냄")

        // 모든 대상에게 이벤트 푸쉬
        //io.sockets.emit("hi", "모두에게")
        
        // 자신제외 모든 대상에게 이벤트 푸쉬
        socket.broadcast.emit("hi", data.msg)
        // 비밀대화 방을 파서 채팅할 때 하자

        // 대상에게 보낼 예정
        // 이벤트를 푸쉬할 유저의 id\값을 to 메서드의 매개변수로 전달
        io.sockets.to(data.id).emit("hi", data.msg);
    })
    // 유저가 나갔을 때
    socket.on("disconnect", ()=>{
        // 유저가 접속을 해제했을 때 실행되는 이벤트
        console.log("유저 나감");
        userId = userId.filter((value)=> value != socket.id);
        console.log(userId);
    })
})

3. main.ejs_socket.io 모듈의 스크립트를 로드하고, 윈도우가 onload 되었을 때 io객체의 connect 메서드를 사용하여 서버단과 연결을 시도한다.

  • socket.on으로 서버단에서 보낸 " hi " 이벤트를 받아 alert로 페이지에 매개변수로 받은 내용을 띄운다.
  • btn.onclick으로 아이디 속성이 btn인 ' 전송하기 ' 버튼을 클릭하면 socket.emit으로 " hi " 이벤트를 서버로 푸쉬한다.
    • emit의 두 번째 매개변수인 객체를 서버단으로 푸쉬한다.
  • 따라서 프론트 단에서는 해당 내용들을 수행한다.
    • ' 전송하기 ' 버튼을 클릭하여 hi 이벤트를 서버단으로 푸쉬한다.
    • 서버 측에서 hi 이벤트를 찾고 해당 이벤트를 실행한다.
      • 서버단의 io.sockets.to(data.id).emit("hi", data.msg)를 실행 한 후, 해당 이벤트를 프론트 단으로 푸쉬한다.
    • 서버단으로 부터 특정 id에 작성한 msg를 보내도록 이벤트를 푸쉬받은 클라이언트 측에서 최종적으로 이벤트를 싱행한다.
<body>
    <input type="text" id="text" placeholder="문자"> <br>
    <input type="text" id="user" placeholder="사용자 아이디"> <br><br>
    <button id="btn">전송하기</button>
</body>
<script>
    window.onload = () => {
        // 소켓 객체를 사용해서 연결
        // io객체의 connect 메서드를 사용해서 연결을 시도한다.
        const socket = io.connect();

        // 클라이언트가 서버측에서 해당 'hi'라는 이벤트를 푸쉬하면 
        socket.on("hi", (data)=>{
            alert(data);
        })
        btn.onclick = ()=>{
            // 클라이언트에서 서버측으로 이벤트를 푸쉬
            socket.emit("hi", {msg : text.value, id: user.value})
        }
    }
</script>

 

 

 

 


socket.io를 이용하여 채팅방 제작

사실 input에 쓴 내용이 실시간으로 페이지에 등록되는 것이라, 채팅방으로 보기엔 힘들다....

#. 폴더의 경로는 다음과 같다.

  • 여기서 app.js와 main.ejs는 이전의 메세지 전송에 사용되었던 파일이다.  현재는 app2.js와 main2.ejs를 사용한다.

1. app2.js_웹 서버를 열기위한 기본세팅을 설정한다.

  • 사용할 모듈을 저장하고 불러온다.
const express = require("express");
const socketio = require("socket.io")
const path = require("path")
  • 서버 인스턴스를 생성한다.
app = express();
  • view엔진의 경로와 ejs사용을 설정한다.
app.set("views", path.join(__dirname,"page"));
app.set("view engine", "ejs");
  • 서버를 대기상태로 만들고, 서버객체를 소켓의 매개변수로 전달한다.
const server = app.listen(6767,()=>{
    console.log("서버열림2")
})

// socket 객체 생성
const io = socketio(server);

2. app2.js_루트경로에서 렌더할 페이지를 설정하고, socket을 이용하여 클라이언트가 접속했을 때와 모든 클라이언트에게 보낼 이벤트를 설정한다.

  • 루트경로( ' / ' )로 접속 시 보여줄 페이지를 설정한다.
app.get ('/',(req,res)=>{
    res.render('main2');
})
  • io.sockets.on("connection",   ~ : 클라이언트가 접속했을 때 동작할 이벤트이다.
  • socket.on("message",  ~  io.sockets.emit("message", data) : 모든 클라이언트에게 이번트를 푸쉬하는 이벤트이다. 클라이언트가 보낸 객체를 data로 받아 다시 클라이언트에게 보내준다.
io.sockets.on("connection", (socket)=>{
    // 클라이언트 접속 했을 때
    socket.on("message", (data)=>{
        // 모든 클라이언트에게 이벤트 푸쉬
        io.sockets.emit("message", data);
    })
})

3. main2.ejs_클라이언트 측에서 소켓 연결을 시도하고, socket.on을 이용하여 누군가가 보낸 메세지를 서버단에서 최종적으로 emit한 내용을 받아 li 태그로 노출한다.

// 클라이언트 소켓 연결 시도.
        const socket = io.connect();
        socket.on("message",(data)=>{
            // 채팅을 받았다는 것은 누군가 채팅을 보냈다는 얘기이다.
            // content에 채팅 태그를 만들어서 넣어주자
            let el = `
            <li>
                <h3>${data.name}</h3>
                <p>${data.message}</p>
                <p>${data.date}</p>
            </li>
            `;
            content.innerHTML += el;
        })

4. main2.ejs_" 메세지 보내기 " 버튼을 클릭 시, input으로 받은 내용들을 객체로 담아 " message " 이벤트를 서버단으로 푸쉬한다.

        btn.onclick = ()=>{
            socket.emit("message",{
                name : user_name.value,
                message : message.value,
                // toString(): new Date()를 문자열로 바꾼다.
                date : new Date().toString()
            })
        }

 

 

 

 

 


Axios

Axios 라이브러리

  • Axios는 브라우저, Node.js를 위한 promise API를 활용하는 HTTP 비동기 통신 라이브러리이다.

 

Axios 특징

  • 운영 환경에 따라 브라우저의 XMLHttpRequest 객체 또는 Node.js의 http api 사용
  • Promise(ES6) API 사용
  • 요청과 응답 데이터의 변형
  • HTTP 요청 취소
  • HTTP 요청과 응답을 JSON 형태로 자동 변경

 

Axios 문법 구성

axios({
  url: 'https://test/api/cafe/list/today', // 통신할 웹문서
  method: 'get', // 통신할 방식
  data: { // 인자로 보낼 데이터
    foo: 'diary'
  }
});

axios 요청(req)파라미터 옵션

  • method : 요청방식. (get이 디폴트)
  • url : 서버 주소
  • baseURL : url을 상대경로로 쓸대 url 맨 앞에 붙는 주소.
  • headers : 요청 헤더
  • data : 요청 방식이 'PUT', 'POST', 'PATCH' 해당하는 경우 body에 보내는 데이터
  • params : URL 파라미터 ( ?key=value 로 요청하는 url get방식을 객체로 표현한 것)
  • timeout : 요청 timeout이 발동 되기 전 milliseconds의 시간을 요청. timeout 보다 요청이 길어진다면, 요청은 취소되게 된다.
  • responseType : 서버가 응답해주는 데이터의 타입 지정 (arraybuffer, documetn, json, text, stream, blob)
  • responseEncoding : 디코딩 응답에 사용하기 위한 인코딩 (utf-8)
  • transformRequest : 서버에 전달되기 전에 요청 데이터를 바꿀 수 있다.
    • 요청 방식 'PUT', 'POST', 'PATCH', 'DELETE' 에 해당하는 경우에 이용 가능
    • 배열의 마지막 함수는 string 또는 Buffer, 또는 ArrayBuffer를 반환합
    • header 객체를 수정 가능
  • transformResponse : 응답 데이터가 만들어지기 전에 변환 가능
  • withCredentials : cross-site access-control 요청을 허용 유무. 이를 true로 하면 cross-origin으로 쿠키값을 전달 할 수 있다.
  • auth : HTTP의 기본 인증에 사용. auth를 통해서 HTTP의 기본 인증이 구성이 가능
  • maxContentLength: http 응답 내용의 max 사이즈를 지정하도록 하는 옵션
  • validateStatus : HTTP응답 상태 코드에 대해 promise의 반환 값이 resolve 또는 reject 할지 지정하도록 하는 옵션
  • maxRedirects : node.js에서 사용되는 리다이렉트 최대치를 지정
  • httpAgent /  httpsAgent : node.js에서 http나 https를 요청을 할때 사용자 정의 agent를 정의하는 옵션
  • proxy : proxy서버의 hostname과 port를 정의하는 옵션
  • cancelToken : 요청을 취소하는데 사용되어 지는 취소토큰을 명시

 

Axios 단축 메소드

axios의 문법대로 사용하는 것보다 더욱 편리하게 사용하기 위한 aliases를 제공한다. 객체 옵션을 함수형으로 재구성한것으로 이해하면 된다.

  • GET : axios.get(url[, config])
    • 단순 데이터(페이지 요청, 지정된 요청) 요청을 수행할 경우
    • 파라미터 데이터를 포함시키는 경우(사용자 번호에 따른 조회) 등의 상황에서 사용한다.
  • POST : axios.post(url, data[, config])
    • 일반적으로 데이터를 Message Body에 포함시켜 보낸다.
  • PUT : axios.put(url, data[, config])
    • REST기반 API 프로그램에서 데이터베이스에 저장되어 있는 내용을 수정하는 목적으로 사용한다.
  • DELETE : axios.delete(url[, config])
    • REST기반 API 프로그램에서 데이터베이스에 저장되어 있는 내용을 삭하는 목적으로 사용한다.
axios.request(config)

axios.get(url[, config])

axios.delete(url[, config])

axios.head(url[, config])

axios.options(url[, config])

axios.post(url[, data[, config]])

axios.put(url[, data[, config]])

axios.patch(url[, data[, config]])

 

 

 

 


비행기 좌석 예약 페이지 제작

#. 폴더의 경로는 다음과 같다.

1. app.js_ 사용할 모듈을 불러오고, 비행기 좌석을 구성할 배열을 생성한다.

  • 사용할 모듈
    • express, ejs, socket.io
  • 비행기 좌석을 생성한다. 좌석의 구역은 총 3개로 나뉘어 있어, 1~3번 구역을 선택할 수 있도록한다.
    • 좌석을 구성한 배열에서 각 숫자의 역할은 다음과 같다.
      • 0번 : 좌석이 아닌 빈 공간
      • 1번 : 예매가 가능한 좌석
      • 2번 : 예매가 완료되어 선택할 수 없는 좌석
    • 각 구역의 좌석들을 seatsArr배열에 담고, 클라이언트가 선택한 구역을 담을 seats 배열을 선언한다.
// 선택된 구역의 자리 들을 보여 줄 배열
let seats = [];

// 1번 구역의 좌석
let temp = [
    [1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
];

// 2번 구역의 좌석
let temp2 = [
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
];

// 3번 구역의 좌석
let temp3 = [
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1],
    [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
];

let seatsArr = [temp, temp2, temp3];
ejs에서 socket.io와 axios를 사용하기 위하여 head 상단에 하단의 코드를 기입하여 사용할 준비를 한다.
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

2. main.ejs_서버에서 생성한 좌석을 가져와 노출하고, 예약 가능한 좌석을 클릭하면 예약을 완료한다.

  • 사이트를 열자마자 보이는 좌석을 설정해야 하므로 디폴트 값으로 0을 설정하여 temp의 좌석이 노출되도록 설정한다.
  • axios.get으로 요청받은 값을 then의 매개변수로 전달한다.
    • lineElem : data에 요청받은 값을 넣고, forEach문으로 좌석을 열 단위로 돌면서 태그와 클래스를 부여한다.
      • 0: (14) [1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
        1: (14) [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
        2: (14) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        3: (14) [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
        4: (14) [1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
    • seatElem : line을 forEach문으로 돌면서 태그와 클래스를 부여하며 시트들을 생성한다.
      • forEach문으로 시트들을 돌면서 setAttribute 메소드를 사용하여 속성을 추가한다.
        • data-x : seatElem를 동작하면서 부여되는 인덱스 값을 부여한다.
        • data-y : lineElem를 동작하면서 부여되는 인덱스 값을 부여한다.
          • 예) 배열의 값(data-x, data-y)
            0: (14) [1(0, 0), 1(1, 0), 0(2, 0), 2(3, 0), ... ]
            1: (14) [1(0, 1), 1(1, 1), 0(2, 1), 1(3, 1), ... ]
    • if문으로 시트 값이 1인 좌석은 enable 클래스를 부여하여 선택할 수 있는 좌석임을 표시하고, 클릭 시, addEventListener로 onClickseat함수를 실행한다.
      • 시트 값이 2인 좌석은 disable 클래스를 부여하여 선택할 수 없는 좌석임을 표시한다.
// 시트 생성 함수
function getseats(selectIndex){
    // 요청 방식 : get 방식
    // 매개변수 : 아이디 값으로 요청
    axios.get("/seats/"+selectIndex).then((e)=>{
        // 요청 이후 응답받은 값이 e
        // 시트 배열이 넘어온다.
        console.log(e);
        let { data } = e;
        data.forEach((line,indexY) => {
            let lineElem = document.createElement("div");
            // 시트 들의 열
            lineElem.classList.add("line");
            line.forEach((seat, indexX)=>{
                let seatElem = document.createElement("div");
                // 시트 들
                seatElem.classList.add("seat");
                // 데이터 속성 이라는 어트리뷰트 속성을 사용
                // setAttribute: 어트리뷰트 속성을 추가하는 메소드
                    // 첫 번째 매개변수 : 속성의 이름
                    // 두 번째 매개변수 : 속성의 값
                seatElem.setAttribute("data-x",indexX);
                seatElem.setAttribute("data-y",indexY);
                // 빈 공간, 예약 가능한 시트, 이미 예약된 시트
                if(seat == 1){
                    seatElem.classList.add("enable");
                    // 시트를 클릭하면 예약 
                    seatElem.addEventListener("click", onClickseat);
                }
                else if(seat == 2){
                    seatElem.classList.add("disable");
                }
                lineElem.appendChild(seatElem);
            });
            content.appendChild(lineElem)
        });
    })
}
getseats(0)

 

3. main.ejs_사이트가 load되면 socket에 연결되고, 서버단에서 보낸 reserve를 받아온다.

  • socket.on으로 서버에서 emit으로 보낸 ' reserve ' 이벤트를 받아 실행한다.
    • ejs에서 emit으로 보내준 selectCount의 값과 현재 ejs에서 선택한 selectedIndex값을 비교하여 두 값이 같으면 선택한 data-x,data-y가 동일한 좌석의 클래스 속성을 변경하여 예매를 진행한다.
  • 구역을 선택하는 select 태그의 값이 변경되면, selectCount의 값을 현재 선택한 selectedIndex의 값으로 변경해준다.
socket.on('reserve',(data)=>{
            if(data.selectCount == selectBtn.selectedIndex){
                let target = document.querySelector(`div[data-x="${data.x}"][data-y="${data.y}"]`);
                target.classList.remove("enable");
                target.classList.add("disable");
            }
        })
        let selectCount = 0;
        selectBtn.onchange = function(){
            content.innerHTML = "";
            //selectedIndex: select 태그의 선택한 옵션의 index를 호출한다.
            selectCount = this.selectedIndex;

            //시트 생성 함수 여기에
            getseats(selectCount);
        }

 

4. main.ejs_좌석을 클릭하면 해당 좌석의 예약여부를 확인하고, 해당 좌석의 정보를 서버단에 보낸다.

  • onClickseat 함수로 좌석 클릭 시, 클릭한 좌석의 예약 여부를 확인하고 예약이 되어있지 않으면 클릭한 좌석의 정보를 서버단으로 보낸다.
    • socket.emit메서드를 이용하여 " reserve "이벤트로 푸쉬 예정이다.
// 시트를 클릭해서 예약하는 함수
        const onClickseat = function(){
            // contains: 매개변수 안의 클래스가 있는지 확인하는 메소드
            if(this.classList.contains("disable")){
                // 이미 예약이 되어 있으면 여기서 끝
                return;
            }
            
            // getAttribute: 매개변수 안의 어트리뷰트 데이터 속성을 호출한다.
            let x = this.getAttribute("data-x");
            let y = this.getAttribute("data-y");
            if(confirm("해당 좌석을 예약 하시겠습니까?")){
                // socket 이벤트를 푸쉬할 예정
                socket.emit("reserve",{
                    x,
                    y,
                    selectCount
                })
            }
            else{
                alert("선택이 취소되었습니다.")
            }
        }

 

5. app.js_ejs에서 좌석 예약을 위해 emit으로 보낸 값을 data로 받아 데이터베이스에서 해당좌석을 예약처리 한 후, 클라이언트에게 예약된 결과값을 보내준다.

io.sockets.on("connection", (socket)=>{
    socket.on("reserve", (data)=>{
        console.log("예약");
        let seatTemp = seatsArr[data.selectCount];
        seatTemp[data.y][data.x] = 2;
        io.sockets.emit('reserve',data);
    })
})

 

 

 

 

 

 

 

728x90