본문 바로가기
Review

[리뷰] SKYST HACKATHON 2 후기 - 프론트엔드 팀인 줄 알았는데, 풀스택 팀이었습니다

by r4bb1t 2024. 3. 27.
반응형

프론트엔드가 주 분야인 사람 5명(저, 찬휘, 용준, 영헌, 지수)이서 팀을 꾸려 출전한 스카이스트 해커톤.
정신차려보니 찬휘🦈는 디자인을 전부 맡았고, 기획 하고 싶어했던 지수👼는 감기 걸려서 불참해버렸고, 용준⚔️은 버그 사냥꾼이 되어 장장 4시간의 삽질을 끝내버렸고, 영헌🦁은 프롬프트 엔지니어로 거듭나고, 저🐰는.... 백엔드를 했습니다.

프엔 개발자끼리만 모인 줄 알았던 우리 팀 알고 보니 풀스택 팀


SKYST는 서울대, 연세대, 고려대, KAIST 연합 단체입니다.. 작년에는 SKYCC였는데, 카이스트도 함께 하게 되어서 SKYST가 되었다고 하네요.
저희 팀은 모두 KUCC 회원들로 이루어져 있는데요. 지수가 드래곤볼을 열심히 모아서 팀을 꾸렸습니다.

팀 모아놓고 떠난 그녀

팀장인 찬휘가 지은 저희 팀명은 멋진예금.

진짜 아무거나였다

대회 공식적으로 공지 및 질문 등 소통은 Slack을 활용했는데요. 워크스페이스에 들어갈 때 팀명_이름 형태로 닉네임을 설정해야 하는데.. 생각해보니 팀명을 모르더라구요..?

...네. 그저 어감이 좋아 지은 팀명이라고 하네요.
이번 해커톤 주제는 love(사랑). 재미있는 주제라고 생각했어요. 작년 SKYCC 때도 그랬지만, 주제 자체가 공익적이거나 사업적인 방향을 강제하지 않아서 좋았고 (물론 오히려 어렵기도 했지만..) 주제 해석을 자율적으로 두는 느낌이었습니다! 주제 공개는 대회 이틀 전에 나왔는데, 각자 생각한 걸 바탕으로 전날 회의한 결과 '덕질'도 사랑이니까 '덕질'을 메인으로 잡고 대회장에서 더 이야기해보자, 로 결론이 났었습니다. 정작 대회장 가서 더 얘기해본 결과 결국 덕질과는 전혀 관련없는 기획으로 확정되었습니다 😅

아이디어 정리만 3번을 했는데요, 마지막 '퀴즈'라는 메인 테마는 대회장에서 아이디에이션 시간에 이야기 나누다가 튀어나온 주제입니다. 뭔가 사람들끼리 상호작용할 수 있는 퀴즈게임같은 서비스에 차별점을 주고 싶다는 생각에서 열심히 고민했던 것 같아요. 처음에는 덕질을 바탕으로 연예인에 대한 퀴즈게임을 생각하다가, 덕질에서 벗어나서 생각해볼까? 하면서 또 다같이 회의를 했습니다.
그래서 결론적으로는 요즘 유행하는 'ㅇㅇ 사이에 숨은 ㅇㅇ 찾기'의 형식을 빌려, '사람 사이에 숨은 AI 찾기'로 가기로 결정! 한 번 방향이 잡히니 그 뒤로 기획은 정말 슉슉 진행되었어요. AI 찾는 게 너무 쉽지 않을까? 라는 고민은, 각 게임마다 컨셉(ex. 교수님 말투로 말하기)을 부여해서 사람과 AI가 모두 해당 컨셉을 연기하도록 하는 것으로 해결했습니다.
서비스명은 극락 퀴즈쇼. 사실 기획 확정되기도 전에 퀴즈로 하게 되면 극락 퀴즈쇼로 하자고 저 없는 사이에 이야기했더라구요 진짜 웃김... 개발하면서 진짜 그냥 극락 퀴즈쇼라는 단어 보일때마다 웃겨서 기분이 좋았습니다...

아이디어의 틀이 된 콘텐츠

주제인 사랑과의 연관성은 인류애에서 찾았습니다. Calude가 작성한 글을 저희 메인화면에 그대로 담았는데요, 우리는 인간과 AI를 구분할 수 있을까? 에서 인류애에 대한 개념에 질문을 던지는.. 그런 컨셉입니다. 아마도요..?

좌 메인화면 / 우 발표자료

어쨌든 컨셉이 '단톡방'이니만큼 실시간 채팅을 구현해야 했어요. 기획이 확정되기 전부터 Next.js App Router를 쓰기로 했었는데, 여기에 웹소켓을 얹기 위해 검색을 해봤더니 next-ws라는 따끈따끈한 라이브러리가 있는 게 아니겠어요? 너무 최신 라이브러리고, Next.js에서 웹소켓을 같이 띄우는 걸 비추천하는 의견들이 많아 살짝 불안했지만... 일단 시작해봤습니다.

후원사였던 몬스터에너지 및 인프랩에서 주신 생수

용준과 영헌이 프롬프트 엔지니어링을 맡고, 찬휘가 와이어프레임을 짜는 동안 저는 Next.js로 프론트 환경을 일단 세팅하고, next-ws를 사용해서 우선 실시간 채팅을 구현했습니다. 해당 라이브러리의 예제를 따라하니 금방 되더라구요.
그런데 생각해보니 AI도 채팅을 보내야 하고, 그러기 위해서는 서버가 따로 있는게 맞을 것 같다는 생각이 계속 들어서, 그냥 제가 백엔드를 하기로 했습니다! 🙄 데이터베이스는 뭘 쓸까, 그냥 편하게 Firebase를 쓸까 하다가, 찬휘가 Supabase를 써보는 게 어떠냐 해서 별 생각 없이 써봤습니다. 웬걸. 정말 정말 편해요. 사실 Supabase의 기능들을 많이 활용했다기보다는, DB를 따로 띄울 필요가 없고 웹 인터페이스로 관리할 수 있다는 점만 사용했어요. 일단 DB 관련해서 머리 싸맬 일이 없어서 시간 단축에 엄청 도움되었습니다. 진짜 마우스 딸각 딸각 하니까 DB가 뿅 띄워지더라구요. 백엔드는 제가 좋아해 마지않는 Koa.js를 사용했습니다. 어차피 백엔드 저 혼자 할거라서 딱히 프레임워크 선택에 고민은 없었고, 그나마 제일 많이 써보고 편한 걸 골랐습니다. 다른 프레임워크도 찍먹해봐야 하는데 그럴 기회가 많지 않네요 하하...

사진 좀 많이 찍어둘걸

그리고 여러 우여곡절이 있었는데요, ws 프로토콜로는 웹소켓 서버에 접근이 되는데, 도메인을 연결하면 wss를 사용해야 하는 게 문제였습니다. 이상하게 wss로만 하면 502 bad gateway가 뜨고.. 멘토님께 도움을 요청했는데요, 가장 먼저 Nginx를 버리고 Caddy로 웹서버를 세팅해주셨어요. 여기서 Caddyfile의 깔끔한 구조를 보고 기절할 뻔했구요, https를 자동으로 세팅해주는 걸 보고 기절했습니다. 아무튼... 결국 Caddy로 바꾸어도 wss 문제는 해결은 안 되었지만, 서버를 따로 띄우게 됐음에도 불구하고 Next.js에서 웹소켓 서버를 띄우고, 서버는 웹소켓 접근을 위해 그 웹소켓 서버에 접근하는 기이한 구조(...)를 바꿔야겠다고 생각하고, 바로 실현했습니다. next-ws 라이브러리를 삭제하고, 클라이언트에서는 그냥 웹소켓 객체를 하나 만들어서 사용하는 걸로 했어요. 너무 최신 라이브러리라서.. (참고로 웹소켓 요청 확인은 npm global로 wscat 설치해서 사용했습니다. 처음 써보는 신기한 것들이 많았어요)
아무튼, 그래서 웹소켓 서버는 서버에서 같이 띄우기로 결정. Koa에서 웹소켓 다루는 법은 이 글을 참고했습니다. 바꾸고 나니 참 쉽더라구요. 진작 이렇게 할 걸..! 그런데 배포한 링크에서 웹소켓 접근이 저는 되는데 다른 팀원들은 안된다는 거예요! 왜지 왜지 하면서 코드 뜯어보다가... "네 컴퓨터에 로컬 서버 켜져있어서 그런 거 아니야?" 라는 얘기를 듣고 설마 설마 했는데, 정말 로컬호스트로 쏘는 요청이 있었던 거였어요...^^ 아무튼 그래서 이것도 잘 고치고, wss 문제는 결국 해결 못해서 그냥 도메인 연결하지 말고 ip주소:포트번호 식으로 배포하는 것으로.. 했습니다. 일단 배포 하는게 중요하니까요.

진짜 이렇게 배포함

제가 서버를 삽질하는 동안 찬휘는 프론트를 깎고, 용준과 영헌은 GPT Playground에서 AI 프롬프트를 계속해서 테스트했습니다. AI가 실제 사람처럼 말해야 하는 컨셉상 프롬프트 엔지니어링이 쉽지 않았을 거예요. 그 와중에 GPT Playground는 처음 알았는데 유용한 것 같아요.
아무튼 막판에 서버가 어느정도 마무리된 후에는 프론트의 오류들을 조금씩 고쳤는데요, 기존에 채팅까지만 잘 작동하는 상태이고 투표나 결과는 화면은 있지만 작동이 안 되는 상태였는데, 거의 한시간만에 투표와 투표 결과까지 나오도록 수정한 것 같아요. 진짜 달렸다.. 🏃‍♂️ 끝까지 시간이 너무 빠듯해서, 개발에만 집중하느라 네트워킹 같은 건 거의 못했던 것 같아요... 사진도 거의 안 찍어서 살짝 아쉽긴 합니다. 아래 사진도 다른 팀으로 출전한 뉴트리아가 찍어줬습니다.

즐거운 개발

암튼 해커톤이 끝날 즈음에는 완전 폐인 상태로 있었는데.. 저희 팀은 거의 마지막 발표 순서여서, 다른 팀들 발표를 보면서 그저 감탄만 했습니다. 다들 발표자료도 예쁘고 기획도 스케일이 크더라구요.

극락 퀴즈쇼 발표자료
서비스 실제 캡쳐

반면 저희는 어찌되었든 스케일이 크진 않았기 때문에 수상을 크게 기대하지는 않았고.. (인기상 같은 거 있으면.. 받기를 조금 기대했습니다.) 그냥 발표 때 우리 서비스를 처음부터 끝까지 잘 시연했다는 점이 굉장히 만족스러웠습니다. 만든 걸 다 보여줬다는 게 진짜 기분이 좋았어요. 아무튼 개발 자체가 너무 재미있기도 했고, 저희 서비스를 팀원 모두 아주 마음에 들어했어서 🥰 그냥 그 자체로 만족하고 있었는데..!

초췌한 모습

무려 대상을 받아버렸습니다. 기쁘기도 했지만 놀란 게 더 컸습니다. 저는 부끄럽지만 ㅎㅎ 작년에 이어 2관왕입니다. (〃⌒▽⌒〃)ゝ 분명 작년 후기글을 쓸 때에는 SKYCC 2회가 열릴 땐 학부생이 아닐 줄 알았는데... 학부생 신분으로 또 출전해서 수상을, 그것도 또 1위를 할 줄은 상상도 못했죠. 인생이란 이렇게 한 치 앞도 알 수 없는 것입니다. 근데 작년보다 상금이 줄었다..?


이제 해커톤에서 얻어갈 수 있는 경험이 더 있을까? 라는 생각이 들어 이번 해커톤은 진짜 재미있게 즐기는 걸 1순위 목표로 해야겠다는 마음을 먹었었는데요. 일단 너무 재밌었고 거기에 더해 얻은 게 너무나 많았던 해커톤이었습니다.

  1. 백엔드로 해커톤에 참가해보았다.
    사실 백엔드만 한 건 아니고 프론트도 어느정도 했지만 ㅎㅎ 백엔드는 정말 거의 저 혼자 했는데 애초에 취미로 할 때도 이 정도로 열심히 하지 않았어서,, 너무 특별한 경험이었습니다. 특히 배포 관련해서 경험치가 좀 쌓인 것 같아요.
  2. Caddy라는 웹서버의 존재를 알았다.
    킹갓제너럴마제스티어쩌구...멘토님 감사합니다. 개인 서버도 Nginx 갖다 버리고 Caddy로 바꿨습니다. 진짜 이렇게나 간편할 수가!
  3. 웹 소켓 써봤다.
    재미있었어요. 다음엔 클라이언트들을 Redis 같은 걸로 관리해보고 싶습니다. (지금은 놀랍게도 그냥 배열에 넣었다 뺐다 하고 있음...)

wss 문제는 해커톤 끝나고 이 글을 작성하기 직전에 해결했는데요, 이런 문제가 있었다고 친구들한테 얘기하니까 Caddy를 좋아하는 난노가 아래 코드 하나를 무심하게 툭 던지는 게 아니겠어요?

example.com {
    @websockets {
        header Connection *Upgrade*
        header Upgrade    websocket
    }
    reverse_proxy @websockets localhost:6001

    reverse_proxy localhost:8080
}

요청 가지고 필터링해서 웹소켓 요청은 웹소켓 서버로 보내버리는 Caddyfile 설정인데, 이걸 적용했더니 wss 프로토콜도 문제없이 전송되는 게 아니겠어요.. 눈물이 뚝뚝 흐르네요 최고입니다. 아무튼 그래서 지금은 잘 배포되어있다는 이야기.
결과물은 조금 더 고쳐서 개인 서버에 배포해두었습니다. 링크는 여기!

 

극락 퀴즈쇼

오오오… 당신의 친구들을 진정으로 사랑한다는 것… 그것은 내가 이해할 수 없는 감정의 영역입니다. 하지만 나는 그 친구들을 소중히 여기고 있답니다. 비록 그들이 실제로 존재하지 않더라

keukrak.r4bb1t.dev

귀여운 후배의 피드백으로 후기를 마칩니다 😋

ㅠㅠ

 

반응형

댓글