프로젝트 개요
↗️ KW HACKATHON 광운대학교 연합 동아리 해커톤
- 팀 구성 : 디자인 및 프론트 1 / 백엔드 2 / 기획 1 / 인프라 2
- 프로젝트 주제 : 예비군 승차 공유 서비스
- 개발 기간 : 2024-11-11~2024-11-16
프로젝트 동기
예비군들이 조기 퇴소나 승차 공유같은 목적을 가지고 ‘에브리타임’ 서비스의 게시글로 모집하는 경우를 보고 이 기능을 특화한 서비스의 필요성을 갖게 되어 프로젝트를 시작하게 되었다.
실제로 설문조사를 실시한 결과 입퇴소 부담요인에 교통비용, 이동 시간, 대중교통 이용 순으로 높았으며, 조기 퇴소 참가자 모집 시 적극적인 참여자에 대한 수요 요구가 많았다. 또한 자차보다는 대중교통 선호가 더 많았다.
부담스러운 교통 비용 ➡️ 승차 공유 희망자를 위한 커뮤니티 제공
원치 않는 소극적인 팀원 ➡️ 조기 퇴소 희망자 모집 게시판 기능
버스 예약 불가 ➡️ 총학생회 연계 버스 통합 예약 서비스
💻 사용 스택
Cooperation
Git | Github | Notion | Discord | Figma
Infra
AWS EC2 | AWS RDS | AWS ELB | AWS Route 53
Back-end
Java | Spring Boot | Spring Security | Spring Data JPA | MySQL | JWT | Web Socket | RabbitMQ | Erlang
Front-end
TypeScript | React | React Query | React Hook Form | Tailwind CSS | Axios | Zod | Vercel
핵심 기능
1️⃣ 승차 공유자 모집 - 게시판 및 채팅 기능
2️⃣ 조기 퇴소자 모집 - 게시판 및 채팅 기능
3️⃣ 버스 예약 시스템 - 입력 폼 및 조회 기능
📃 API 명세
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
🎨 디자인
![]() |
![]() |
👩🏻💻나의 역할
- 일대일 채팅 기능
- 사용 스택 : RabbitMQ, Web Socket, STOMP protocol
이전에는 STOMP + Redis 로 채팅을 구현한 경험이 있었다. 여기서 문제점은 서버와 프론트 사이에 큐가 없어 메시지 유실 가능성이 높아지고 사용자가 많아지게 되면 관리가 어렵다는 점이었다. 이에 RabbitMQ 라는 외부 메시지 큐를 사이에 두어서 유지보수의 장점을 갖고 가기로 하였다. RabbitMQ 에 대한 내용은 추후에 다루도록 하겠다.
RabbitMQ 에서의 권한 설정 기능도 사용해 보았다. 관리자 페이지를 단순히 포트번호 :15672 로 접근가능한데 권한 분리를 하지 않으면 타 사용자가 모든 메시지를 확인할 수 있다. 따라서 MQ 에서는 권한을 부여할 수 있는 기능을 제공하고 나는 사용자의 권한은 none으로 설정하였다.
웹소켓을 백엔드 서버만 개발한 상태에서는 테스트에 어려움이 있다. 일단 Stomp+Websocket을 테스트하는 기능을 postman에서 지원하지 않는다. (postman에서 테스트는 가능하지만 null문자 인식문제로 왔다리 갔다리 한다.) 또한, 기존에 테스트용으로 많이 사용하던 APIC 구글 확장프로그램이 더 이상 지원되지 않는다. 따라서 타 개발자가 만든 Web Socket 디버거를 이용해야 했고 이 과정에서 많은 시간이 소요되었다.
또한, 서버만 개발할 당시 SocketJS를 이용했었다. SocketJS는 웹소켓 프로토콜(ws 또는 wss)을 https 또는 http로 라우팅 해주어서 웹소켓을 http 환경에서 구동할 수 있게 해 주는 기능이다. 하지만 프론트에서 웹소켓 연결이 지속적으로 안 되는 문제가 발생하였다. 하지만, SocketJS를 사용하지 않고 웹소켓 프로토콜 환경을 그대로 사용하면 연결에 성공하였는데 그 이유는 다음과 같았다. React의 WebSocket 라이브러리에서는 HTTP 기반이 아닌 순수한 웹소켓 즉, WS 를 기대하기 때문에 백엔드에서 아무리 연결 요청을 보내도 호환성 문제로 인해 연결 시도를 잡지 못하는 것이었다.
Spring Security와 Web Socket Security 는 독립적으로 동작하기 때문에 Interceptor를 이용해 별도의 인증을 구현할 필요가 있었다. 그 이유에는 크게 기능적 차이, 라이프사이클 차이, 구현차이가 있는데 자세한 내용은 나중에 다뤄보겠다. 따라서 CORS 설정도 별도로 설정해줄 필요가 있다. 또한 STOMP status 에 따라 JWT 토큰 인증 여부를 결정할 수 있다. 연결시도시, Subscribe 시, 메시지 전송 시 등 다양한 선택지가 존재한다. 하지만 메시지 전송마다 인증을 적용하면 성능에 안 좋으므로 연결시도 마다 토큰 인증을 하도록 구현하였다.
환경설정 파일인 application.yml 파일을 설정하는 데 있어서 타 블로그에서 yml과 property 파일을 동시에 운영하며 민감한 정보를 별도로 관리하는 것을 보게 되었고 이를 적용하여 구현하였다. 또한, 로컬과 배포 환경을 별도로 파일을 구분하여 구성하였다.
아쉬운 점
급하게 개발하는 과정에서 채팅에 대한 에러 처리와 RabbitMQ의 listener와 producer 기능을 제대로 도입하지 못했다는점, 큐 분리를 세분화하지 못했다는 아쉬움이 있다.
또한, 쿼리 최적화와 게시판 기능이 승차 공유 게시판, 조기 퇴소 게시판으로 기능이 같은 것 이 반복된다는 점에서 중복된 코드를 생성한다는 것에 대한 의문 점이 있다.
기능상 일대일 채팅보다는 다대다 채팅이 사용자간 소통이 원활할 것이라는 추후 개선점이 있었다. 이후에는 다대다 채팅 기능으로 발전시킬 계획이다.
마무리
신속하게 개발하기 위해 협업 툴을 적극적으로 사용하는 계기가 되었던 것 같다. 또한, 채팅기능을 5일 안에 개발할 수 있을까라는 불안감이 있었지만 팀원들간 신속한 피드백과 노력으로 극복한 것 같아 뿌듯하고 개발 후 채팅 기능에 대해 더 자세히 알아보면서 미쳐 알지 못한 자세한 기능까지 알 수 있었다. 그 예로 RabbitMQ의 virtual host를 통해 가상 host로 분리하는 기능이 있는 것을 알 수 있었는데 이를 좀 더 공부해보고 싶다.
교수님들에게 큰 호응을 받아 ‘대상’을 수상하였고 실제 서비스를 위해 지속적으로 개선할 계획이다. 실제 사용자 경험을 통해 얻을 수 있는 피드백과 배움을 더 얻고 싶고 최적화를 통해 사용자 편의성을 고려하는 서비스를 개발하고 싶다.