-
[TIL] 타워 디펜스 팀 프로젝트 발제 (D-4)TIL-sparta 2024. 6. 17. 21:45
> 팀 프로젝트 발제 이후 프로젝트의 소켓 이벤트 패킷 명세 작성, 기능별 작업 구분 및 할당, 데이터 테이블 작성 등의 상세 계획을 수립했다.학습 키워드: Node.js, express, socket.io
1. 프로젝트 회의 진행
요약) 데이터 테이블, 패킷 구조 설계:
프로젝트에서 사용할 여러가지 데이터 테이블 (asset 파일들) 및 redis에 저장될 데이터의 구조를 미리 설계했다. 패킷 구조 설계에도 시간을 많이 썼지만 불확실한 부분들이 조금 있었는데, 검증 로직을 어떻게 짜게 될지 미리 정하기가 어려워서 결과적으로 일부 확실한 항목들만 기입하고 나머지는 기능 구현 시 필요에 따라 채워 넣기로 했다.
2. 한참 전 commit 내용 수정하기
요약) 오래 전 커밋의 메세지를 수정할 때 사용:
// commit 이름 뒤에 '~'를 붙여야 함 git rebase --interactive [commit]~
우선 위의 명령어를 실행하면 다음과 같은 내용으로 vi 에디터가 실행된다.
여기서 수정하려는 커밋의 앞에 있는 'pick' 을 'edit' 으로 수정하고 :wq 하면 git이 rebase 진행중인 상태로 해당 커밋에 머물게 되는데, 그 상태에서 다음과 같이 git commit --amend를 --all 옵션과 함께 실행한다.
// 메세지만 수정하려면 --no-edit 옵션은 제거한다. git commit --all --amend --no-edit
커밋 수정이 완료되면 git rebase --continue로 rebase를 재개시키면 다시 이후 커밋들을 추가하면서 커밋 수정 작업이 완료된다. 주의할 점은 이 방식은 해당 커밋 이후의 커밋을 다시 붙여넣기 때문에 commit history가 새롭게 쓰이는 형태로 진행된다. 따라서 이미 push한 branch에서 이 작업을 수행하면 커밋 불일치로 에러가 발생할 수 있다. 만약 작업 후 그러한 상황에 놓였다면 이전 TIL을 참고하여 해결하자.
3. 기타 사항
socket.io 사용법 게릴라 특강 (강창민 튜터님):
// 특강에서 작성된 코드 const express = require("express"); const http = require("http"); const { Server } = require("socket.io"); const app = express(); const server = http.createServer(app); // 나는야 서버 인스턴스야! const io = new Server(server, { cors: { origin: "*", methods: ["GET", "POST"], // WebSocket Handshake allowedHeaders: ["Authorization"], // JWT }, }); app.use(express.json()); const socketMap = new Map(); // { nickname - socket } // 뭐 하는지는 모르는 미들웨어지만 일단 다 잘되면 next 부르는 것은 국룰! io.use((socket, next) => { // 여기서 내(클라이언트)가 전달해주는 닉네임으로 세팅! socket.data.username = socket.handshake.auth.nickname; next(); }); // 채팅 만든다고 했어요! // 전체 채팅 // 룸 채팅 // DM은 사람답게! // 룸은 한명이 여러개의 룸에 동시에 있을 수 있어요! io.on("connection", (socket) => { socketMap.set(socket.data.username, socket); console.log( `새로운 키보드워리어 ${socket.data.username}님께서 입장을 하셨습니다!` ); socket.on("all_chat", (msg) => { io.emit("all_chat", { username: socket.data.username, msg }); }); // 내가 지금 현재 어느 룸에 들어가있는지 알려주렴! socket.on("rooms", () => { const rooms = Array.from(socket.rooms); socket.emit("rooms", rooms); }); socket.on("join", (room) => { socket.join(room); io.to(room).emit( "system", `채널 ${room}에 키보드워리어 ${socket.data.username}님께서 입장을 하셨습니다!` ); }); socket.on("leave", (room) => { socket.leave(room); io.to(room).emit( "system", `채널 ${room}에서 키보드워리어 ${socket.data.username}님께서 퇴장을 하셨습니다!` ); }); // 어느 룸에서 채팅을 칠것인가! 공지방? 잡담방? 기타 등등... socket.on("room_chat", ({ room, msg }) => { io.to(room).emit("room_chat", { room, username: socket.data.username, msg, }); }); socket.on("dm", ({ to, msg }) => { const target = socketMap.get(to); // socket 인출! if (!target) { socket.emit("dm", { username: "SERVER", msg: "잘못된 상대방 닉네임입니다!", }); } else { socket.to(target.id).emit("dm", { username: socket.data.username, msg, }); } }); socket.on("disconnect", () => { console.log( `키보드워리어 ${socket.data.username}님께서 접속 종료를 하셨습니다!` ); socketMap.delete(socket.data.username); }); }); server.listen(3000, () => { console.log(`헬게이트 오픈!`); });
socket과 io 서버의 여러가지 기능들의 사용법에 대한 설명 이후 심플한 채팅 앱을 구현하여 사용 예시를 보여주셨다. 이 중에서 처음보는 부분은 서버 인스턴스의 cors 설정이다. 이전 프로젝트에서는 new Server()에서 아무런 인자를 사용하지 않았었는데, 인자에 서버 객체와 옵션 객체를 넘겨주면 서버에 여러가지 설정이 가능한 것으로 보인다.
// 이전 프로젝트에서 사용된 io initialization 코드 import { Server as SocketIO } from "socket.io"; import registerHandler from "../handlers/register.handler.js"; const initSocket = (server) => { const io = new SocketIO(); io.attach(server); registerHandler(io); }; export default initSocket;
--
REFERENCES:> 팀 프로젝트 spec
> 팀 프로젝트 repo
> StackOverflow, "How do I modify a specific commit?", 답변 참고
728x90'TIL-sparta' 카테고리의 다른 글
[TIL] 타워 디펜스 팀 프로젝트 진행 (D-2) (0) 2024.06.19 [TIL] 타워 디펜스 팀 프로젝트 진행 (D-3) (0) 2024.06.19 강의 과제) 전송 계층, TCP, UDP, TCP 오류, 흐름 제어, 혼잡 제어 (2) 2024.06.16 프로그래머스) 멀쩡한 사각형 풀이 (Java) (2) 2024.06.15 [TIL] 심화 주차 개인 과제 제출 (D-Day) (0) 2024.06.14