
WebSocket을 활용한 좌석예매 하기
영화관에서 표를 예매하거나 기차, 버스, 비행기등 좌석을 예매 할때 동시에 같은 자리를 예약하는 경우가 발생할 수 있기 때문에 socket의 장점인 실시간 접근을 이용하여 중복 예매를 방지 할 수 있습니다.
사용 모듈
npm init -y
npm install express socket.io ejs nodemon
page/main.ejs
<!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>Document</title>
<style>
/* */
.line {
overflow: hidden;
}
.seat {
margin: 5px;
float: left;
width: 30px;
height: 30px;
border-radius: 3px;
}
.enable {
background-color: gray;
}
.disable {
background-color: aqua;
}
</style>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div>airplane</div>
<select name="" id="selectBtn">
<option value="0">airplane 1</option>
<option value="1">airplane 2</option>
<option value="2">airplane 3</option>
</select>
<div id="content"></div>
</body>
<script>
window.onload = () => {
// connect 메소드를 사용하여 연결
// io는 /socket.io/socket.io.js"에서 가져온 전역객체
const socket = io.connect();
// on 메소드 : 특정 이벤트가 발생했을때 실행할 콜백 함수를 등록
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 tag의 옵션의 인덱스 번호 호출
selectCount = this.selectedIndex;
// 시트 생성 함수
getseats(selectCount);
};
const onClickSeat = function () {
// 예약이 된 좌석이면 리턴시킴
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("노노요");
}
};
function getseats(selectIndex) {
// 요청 응답으로 시트를 가져올 예정
// 변수로 담을 예정
// CDN으로 axios 활용
// 요청은 get방식 매개변수는 아이디 값으로 요청
// /seats/0 으로 get 요청을 보냄
axios.get("/seats/" + selectIndex).then((e) => {
console.log(e);
let { data } = e;
// data의 길이는 4 닌까 4줄 출력
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);
};
</script>
</html>
app.js
// 비행기 좌석 만들기
// 1, 2, 3번 비행기 좌석 예약
// 사용할 모듈
// socket.io express ejs
const express = require("express");
const path = require("path");
const socketIo = require("socket.io");
const app = express();
// 선택된 좌석을 보여줄 배열
let seats = [];
let temp = [
[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 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],
];
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];
// 선택한 비행기의 인덱스
let index = 0;
app.set("views", path.join(__dirname, "page"));
app.set("view engine", "ejs");
app.use(express.urlencoded({ extended: false }));
app.get("/", (req, res) => {
res.render("main");
});
app.get("/seats/:id", (req, res) => {
index = req.params.id;
seats = seatsArr[index];
res.send(seats);
});
const server = app.listen(8080, () => {
console.log("Server On");
});
const io = socketIo(server);
io.sockets.on("connection", (socket) => {
socket.on("reserve", (data) => {
console.log("Reservation");
let seatTemp = seatsArr[data.selectCount];
seatTemp[data.y][data.x] = 2;
io.sockets.emit("reserve", data);
});
});
결과


728x90
'Nodejs' 카테고리의 다른 글
| [NodeJs] multer를 활용한 이미지 업로드 (0) | 2023.09.06 |
|---|---|
| [NodeJs] Cors와 Axios를 활용한 간단한 게시판 만들기 (0) | 2023.09.06 |
| [NodeJs] WebSocket을 활용한 채팅방 구현 (0) | 2023.08.31 |
| [NodeJs] Sequelize 알아보기 (0) | 2023.08.30 |
| [NodeJs] Express-session 알아보기 (0) | 2023.08.30 |