실시간 경매 시스템 만들기(서버센트이벤트, 스케줄링)
DB는 mysql을 사용한다. 필요한 것들을 설치해준다.
D:\code\node\auction>npm i cookie-parser dotenv express express-session morgan multer nunjucks
added 101 packages, and audited 102 packages in 16s
15 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
D:\code\node\auction>npm i -D nodemon
added 29 packages, and audited 131 packages in 18s
19 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
D:\code\node\auction>npm i sequelize sequelize-cli mysql2
added 128 packages, and audited 259 packages in 40s
38 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
D:\code\node\auction>npx sequelize init
Sequelize CLI [Node: 20.16.0, CLI: 6.6.2, ORM: 6.37.3]
Created "config\config.json"
Successfully created models folder at "D:\code\node\auction\models".
Successfully created migrations folder at "D:\code\node\auction\migrations".
Successfully created seeders folder at "D:\code\node\auction\seeders".
필요한 모델들을 작성해주고 db:create 를 수행한다.
auction.js, good.js, user.js 파일 생성 후 작성한다.
D:\code\node\auction>npx sequelize db:create
Sequelize CLI [Node: 20.16.0, CLI: 6.6.2, ORM: 6.37.3]
Loaded configuration file "config\config.json".
Using environment "development".
Database nodeauction created.
로그인 기능을 위해 passport, bcrypt도 같이 설치
D:\code\node\auction>npm i passport passport-local bcrypt
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way
to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated npmlog@5.0.1: This package is no longer supported.
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated are-we-there-yet@2.0.0: This package is no longer supported.
npm warn deprecated gauge@3.0.2: This package is no longer supported.
added 58 packages, and audited 317 packages in 26s
42 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
회원가입, 로그인, 경매 시스템에 대해서 작성한 후에 회원가입을 해본 화면이다.
아래는 최초 메인화면
회원 가입 화면
회원 가입 후 로그인 화면
상품 등록 화면
서버센트 이벤트 사용하기
처음에 클라이언트가 서버와 연결을 한 번 맺으면 이제 HTTP에서는 클라이언트 요청을 서버로부터 응답을 받을 수가 있는데 웹소켓이나 서버센트 이벤트는 서버가 먼저 데이터를 클라이언트로 내려 보내줄 수가 있다.
그런데 웹소켓과 서버센트 이벤트가 다른 점은 웹소켓은 양방향으로 클라이언트에서 서버로 서버에서 클라이언트로 서로 왔다 갔다 할 수 있는데 서버센트 이벤트는 서버에서 클라이언트로만 일방향으로 데이터를 보내줄 수 있다.
예를 들어 서버에서 클라이언트로 보내는 알림이나 서버 시간이 필요할 때 서버센트 이벤트를 쓰면 된다.
경매서비스도 서버시간 기준으로 판단을 할 것이다.
서버센트 이벤트는 sse 이다. 웹소켓도 쓰기 때문에 같이 설치해준다.
D:\code\node\auction>npm i sse socket.io
added 21 packages, and audited 338 packages in 9s
42 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
경매시간을 서버시간 기준으로 받아와서 아래와 같이 표시를 해준다.
서버 시간을 서버 센터 이벤트로 받아와서 갱신이 된다.
개발자도구 network 탭에서 확인하면 매초 서버시간을 받는 것을 확인할 수 있다.
경매 입찰 관련 코드를 작성하고 2개의 아이디로 로그인 한 다음에 입찰을 진행해본다.
2개 아이디 모두 방에 입장한 화면이다.
나이스데이 계정으로 2000원으로 입찰하면 양쪽 화면에 다 출력된다.
굿데이 계정으로 500원으로 입찰하니 경고가 발생하고 입찰되지 않는다.
1500원으로 입찰하였을 경우도 경고 팝업이 발생한다.
아래와 같이 기존 금액보다 높으면 정상적으로 입찰이 진행된다.
스케줄링 구현하기
노드에서 정해진 시간 후에 낙찰받을 수 있게 하는 기능을 구현.
node-schedule을 설치한다.
D:\code\node\auction>npm i node-schedule
added 5 packages, and audited 343 packages in 2s
42 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
node-schedule 단점은 서버가 재시작 되었을 경우 전부 사라진다.
그렇기 때문에 다시 등록할 수 있는 코드가 작성해주어야 한다. (checkAuction.js 에 작성한다.)
경매 프로그램처럼 금액과 관련된 중요한 서비스일 경우 경매 낙찰은 성공하고 돈은 안 빠져 나가는 현상이 생기면 안되기 때문에 transaction을 적용해주어야 한다.
const t = await sequelize.transaction();
...
transaction : t,
...
await t.commit();
...
await t.rollback();
...
낙찰 내역이 정상적으로 나타나고 보유 자산도 경매 금액까지 빠졌는지 확인이 가능하다.
node-schedule 패키지로 등록한 스케줄은 노드 서버가 종료될 때 같이 종료 되기 때문에 운영체제의 스케줄러를 사용하는 것이 좋다.
윈도우에서는 schtasks가 대표적이고, 맥과 리눅스에서는 cron이 대표적이다.
노드에서는 이 두 프로그램의 명령어를 child_process를 통해 호출할 수 있다.