본문 바로가기

clone toy projects

스케쥴링 구현 및 프로젝트 마무리 [흐름만 보기] 카운트다운이 끝나면 더 이상 경매를 진행할 수는 없지만, 아직 낙찰자가 정해지지 않았습니다. 경매 종료를 24시간 후로 정했으므로 경매가 생성되고 24시간이 지난 후에 낙찰자를 정하는 시스템을 구현해야 합니다. 이럴 때 node-schedule 모듈을 사용합니다. npm i node-schedule schedule 객체의 scheduleJob 메서드로 일정을 예약할 수 있습니다. 첫 번째 인수로 실행될 시각을 넣고, 두 번째 인수로 해당 시각이 되었을 때 수행할 콜백 함수를 넣습니다. 경매 모델에서 가장 높은 가격으로 입찰한 사람을 찾아 상품 모델의 낙찰자 아이디에 넣어주도록 정의했습니다. 또한, 낙찰자의 보유 자산을 낙찰 금액만큼 뺍니다. {컬럼: sequelize.literal(컬럼 - 숫자)}는 시.. 더보기
서버센트 이벤트 사용하기 [흐름만 보기] 경매는 시간이 생명입니다. 특히 온라인 경매이므로 모든 사람이 같은 시간에 경매가 종료되어야 합니다. 따라서 모든 사람에게 같은 시간이 표시되어야 합니다. 하지만 클라이언트의 시간은 믿을 수 없습니다. 너무나도 손쉽게 시간을 변경할 수 있기 때문입니다. 따라서 서버 시간을 받아오는 것이 좋습니다. 폴링이나 웹 소켓을 통해서 서버 시간을 받아올 수도 있지만, 이번 예제에서는 서버 센트 이벤트를 사용해서 서버의 시간을 받아올 것입니다. 주기적으로 서버 시간을 조회하는 데는 양방향 통신이 필요하지 않기 때문입니다. 웹 소켓도 사용합니다. 웹 소켓은 경매를 진행하는 동안에 다른 사람이 참여하거나 입찰했을 때 모두에게 금액을 알리는 역할을 할 것입니다. 서버 센트 이벤트와 웹 소켓은 같이 사용할 수 있습니다. S.. 더보기
프로젝트 구조 갖추기 [흐름만 보기] 기본 패키지 구성 기본 폴더구조 구성 npx sequelize init 사용자 모델은 이메일(email), 닉네임(nick), 비밀번호(password), 보유 자금(money)으로 구성됩니다. 사용자가 입찰을 여러 번 할 수 있으므로 사용자 모델과 경매 모델도 일대다 관계입니다. 상품 모델은 상품명(name), 상품 사진(img), 시작 가격(price)으로 구성됩니다. 사용자 모델과 상품 모델 간에는 일대다 관계가 두 번 적용됩니다. 사용자가 여러 상품을 등록할 수 있고, 사용자가 여러 상품을 낙찰 받을 수도 있기 때문입니다. 등록한 상품과 낙찰 받은 상품, 두 관계를 구별하기 위해 각각 Owner, Sold로 관계명을 지정했습니다. 이는 각각의 OwnerId, SoldId 컬럼으로 상품 모델에 추가.. 더보기
이미지를 포함한 채팅 마지막으로 GIF 이미지를 전송하는 것을 구현해보겠습니다. 프론트 화면에서 이미지를 선택해 업로드하는 이벤트 리스너를 추가합니다. POST /room/{{room._id}}/gif 주소에 상응하는 라우터를 작성합니다. 9장의 이미지 업로드와 방식이 같습니다. uploads 폴더에 사진을 저장하고, 파일명에 타임스탬프(Date.now())를 붙이고, 사이즈를 제한했습니다. 파일이 업로드된 후에는 내용을 데이터베이스에 저장하고, 방 안에 있는 모든 소켓에 채팅 데이터를 보냅니다. 이제 이미지를 제공할 uploads 폴더를 express.static 미들웨어로 연결해봅시다. 핵심 정리: • 웹 소켓과 HTTP는 같은 포트를 사용할 수 있으므로 따로 포트를 설정할 필요가 없습니다. • 웹 소켓은 양방향 통신이므.. 더보기
채팅 기능 구현하기 프런트에서는 서버에서 보내는 채팅 데이터를 받을 소켓 이벤트리스너가 필요합니다. chat.html 파일에추가합니다. socket에 chat 이벤트 리스너를 추가했습니다. chat 이벤트는 채팅 메시지가 웹 소켓으로 전송될 때 호출됩니다. 채팅 메시지 발송자(data.user)에 따라 내 메시지(mine 클래스)인지 남의 메시지 (other 클래스)인지 확인한 후 그에 맞게 렌더링합니다. 채팅을 전송하는 폼에 submit 이벤트 리 스너도 추가했습니다. 채팅은 여러 가지 방식으로 구현할 수 있습니다. 현재 GIF 채팅방의 경우에는 채팅 내용을 데이 터베이스에 저장하므로 라우터를 거치도록 설계했습니다. 이제 방에 접속하는 부분과 채팅을 하는 부분을 만들어보겠습니다. 먼저 enterRoom 컨트롤러에서 방 접.. 더보기
미들웨어와 소켓 연결하기 이번에는 방에 입장할 때와 퇴장할 때 채팅방의 다른 사람에게 '#12C6B8 님이 입장하셨습니다' 같은 시스템 메시지를 보내려고 합니다. 그런데 사용자의 이름은 세션(req.session.color)에 들어있습니다. Socket.IO도 미들웨어를 사용할 수 있으므로 express-session을 공유하면 됩니다. 추가로 채팅방 접속자가 0명일 때 방을 제거하는 코드도 같이 넣어보겠습니다. app. js와 socket.is 간에 express-session미들웨어를 공유하기위해 변수로 분리했습니다. socket.is 작성 chat.use 메서드에 미들웨어를 장착할 수 있습니다. 이 미들웨어는 chat 네임스페이스에 웹 소켓이 연결될 때마다 실행됩니다. wrap 함수는 미들웨어에 익스프레스처럼 req, re.. 더보기
실시간 GIF 채팅방 만들기 이 장에서는 사람들이 익명으로 참여하여 자유롭게 GIF 파일을 올릴 수 있는 채팅방을 만들어보겠습니다. 몽고디비와 몽고디비 ODM인 몽구스를 사용할 것입니다. 몽구스를 설치한 후, 몽구스 스키마를 생성하겠습니다. 채팅방 스키마와 채팅 내역 스키마만 있으면 됩니다. 사용자는 익명이니 딱히 저장할 필요가 없습니다. 사용자의 이름은 랜덤 색상으로 구별하겠습니다. 먼저 필요한 모듈을 설치합니다. 이미지를 업로드하고 서버에 HTTP 요청을 할 것이므로 multer와 axios를 같이 설치합니다. color-hash 모듈은 조금 전에 언급했던 랜덤 색상을 구현해주는 모듈입니다. 방 제목(title), 최대 수용 인원(max), 방장(owner), 비밀번호(password), 생성 시간(createdAt) 등을 받습.. 더보기
Soket.IO 사용하기 이전 절의 "ws" 패키지는 간단하게 웹소켓을 사용하고자 할 때 좋습니다. 하지만 구현하려는 서비스가 좀 더 복잡해진다면 Socket.IO를 사용하는 것이 편리합니다. Socket.IO가 할 수 있는 일을 "ws" 패키지가 못한다는 뜻은 아닙니다. Socket.IO에 편의 기능이 많이 추가되어 있다는 뜻입니다. 먼저 Socket.IO를 설치합니다. npm i socket.io@2 그리고 ws 패키지 대신 Socket.io를 연결한다. 먼저 socket.io 패키지를 불러와서 익스프레스 서버와 연결합니다. Socket.IO 객체의 두 번째 인수로 옵션 객체를 넣어 서버에 관한 여러 가지 설정을 할 수 있습니다. 여기서는 클라이언트가 접속할 경로인 "path" 옵션만 사용했습니다. 클라이언트에서도 이 경로와.. 더보기