{"id":22959318,"url":"https://github.com/boostcampwm-2024/web22-liboo","last_synced_at":"2025-08-13T05:31:48.194Z","repository":{"id":259841301,"uuid":"879515133","full_name":"boostcampwm-2024/web22-LiBoo","owner":"boostcampwm-2024","description":"컨퍼런스를 더 가까이, LiBoo 에서 라이브로  🚀","archived":false,"fork":false,"pushed_at":"2024-12-05T07:27:01.000Z","size":15058,"stargazers_count":26,"open_issues_count":13,"forks_count":2,"subscribers_count":3,"default_branch":"dev","last_synced_at":"2024-12-05T08:28:17.815Z","etag":null,"topics":["chat","real-time","socket-io","streaming"],"latest_commit_sha":null,"homepage":"https://liboo.kr","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/boostcampwm-2024.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-28T03:44:42.000Z","updated_at":"2024-12-05T07:27:04.000Z","dependencies_parsed_at":"2024-10-28T10:09:09.273Z","dependency_job_id":"877b5102-83ea-4fed-b36d-97752dc8a1d0","html_url":"https://github.com/boostcampwm-2024/web22-LiBoo","commit_stats":null,"previous_names":["boostcampwm-2024/web22-boostproject","boostcampwm-2024/web22-liboo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostcampwm-2024%2Fweb22-LiBoo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostcampwm-2024%2Fweb22-LiBoo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostcampwm-2024%2Fweb22-LiBoo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boostcampwm-2024%2Fweb22-LiBoo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boostcampwm-2024","download_url":"https://codeload.github.com/boostcampwm-2024/web22-LiBoo/tar.gz/refs/heads/dev","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229737546,"owners_count":18116471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat","real-time","socket-io","streaming"],"created_at":"2024-12-14T18:17:58.232Z","updated_at":"2025-08-13T05:31:48.156Z","avatar_url":"https://github.com/boostcampwm-2024.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![thumbnail](https://github.com/user-attachments/assets/cd7e8ab6-4d94-465d-8817-6ecd18f61125)\n\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"https://liboo.kr\" target=\"_blank\"\u003e\n      \u003cimg src=\"https://github.com/user-attachments/assets/ad322787-ad07-4405-b526-112c882e66ab\" width=\"20%\" /\u003e\n    \u003c/a\u003e\n  \u003ch3\u003e 컨퍼런스를 더 가까이, LiBoo 에서 라이브로 🚀 \u003c/h3\u003e\n\u003c/div\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cp align=center\u003e\n    \u003ca href=\"https://gominzip.notion.site/TEAM-127673f3719e803faf63c70322560d3b?pvs=4\"\u003e Notion \u003c/a\u003e \u0026nbsp; ｜ \u0026nbsp; \n    \u003ca href=\"https://www.figma.com/design/op5Ui6oZ4Zx2D8VUgWOKM0/LiBoo-%F0%9F%9A%80?node-id=1-2\u0026node-type=canvas\u0026t=zcYYT1qCtckcUdcs-0\"\u003e Figma \u003c/a\u003e \u0026nbsp; ｜ \u0026nbsp;\n    \u003ca href=\"https://github.com/boostcampwm-2024/web22-LiBoo/wiki\"\u003e Wiki \u003c/a\u003e \u0026nbsp; ｜ \u0026nbsp;\n    \u003ca href=\"https://github.com/orgs/boostcampwm-2024/projects/17\"\u003e BackLog \u003c/a\u003e \u0026nbsp; ｜ \u0026nbsp;\n    \u003ca href=\"https://blog.liboo.kr\"\u003e Blog \u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cbr/\u003e\n\n\u003e ### 목차\n\u003e [1. 💻 데모 및 배포 링크](#-데모-및-배포-링크) \u003cbr\u003e\n\u003e [2. 🎯 기획 배경](#-기획-배경) \u003cbr\u003e\n\u003e [3. 📺 핵심 기능](#-핵심-기능) \u003cbr\u003e\n\u003e [4. ⚙️ 서비스 아키텍처](#%EF%B8%8F-서비스-아키텍처) \u003cbr\u003e\n\u003e \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[4.1. 호스트](#-호스트) \u003cbr\u003e\n\u003e \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[4.2. 클라이언트](#-클라이언트) \u003cbr\u003e\n\u003e \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[4.3. CI/CD](#-cicd) \u003cbr\u003e\n\u003e [5. 📝 핵심 기술 정리](#-핵심-기술-정리) \u003cbr\u003e\n\u003e \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[5.1. 전체](#전체) \u003cbr\u003e\n\u003e \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[5.2. 프론트엔드의 기술적 도전](#프론트엔드의-기술적-도전) \u003cbr\u003e\n\u003e \u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[5.3. 백엔드의 기술적 도전](#백엔드의-기술적-도전) \u003cbr\u003e\n\u003e [6. 🛠️ 기술 스택](#%EF%B8%8F-기술-스택) \u003cbr\u003e\n\u003e [7. 👊 팀 소개](#team-정권지르기-) \u003cbr\u003e\n\n\u003cbr/\u003e\n\n# 💻 데모 및 배포 링크\n\n- **서비스 링크**: [https://liboo.kr](https://liboo.kr/)\n\n\u003cbr/\u003e\n\n\n# 🎯 기획 배경\n\n네이버 DAN, 토스 Slash, 카카오 If, 인프콘 등 다양한 컨퍼런스가 열리고 있지만, 참여는 여전히 쉽지 않습니다.\n\n높은 경쟁률과 제한된 참가 인원 대신, **더 많은 사람들이 기회를 얻고 컨퍼런스 문화가 더욱 활발**해지기를 바라는 마음으로 LiBoo 프로젝트를 기획했습니다.\n\n### **LiBoo가 만드는 변화와 목표**\n\n- **누구나** 쉽게 기술을 공유하고 배울 수 있는 열린 플랫폼\n- **팀원 간 소규모 공유**부터 **기업 컨퍼런스 협업**까지 지원\n- 더 많은 사람들이 참여할 수 있는 **기술 공유 기회 확대**\n\n\u003cbr/\u003e\n\n# 📺 핵심 기능\n\n![feature-main](https://github.com/user-attachments/assets/36f6b53e-10ac-47c8-bc71-e7e15596ff1b)\n![feature-host](https://github.com/user-attachments/assets/a4092bc8-84eb-4a47-ada6-b135de0e3e85)\n![feature-client](https://github.com/user-attachments/assets/340cd919-0c99-4285-8426-7e6329e97360)\n![feature-chat-client](https://github.com/user-attachments/assets/f0cc9bc0-0d1a-41da-a348-4e2d2f908c7b)\n![feature-chat-host](https://github.com/user-attachments/assets/84fe4260-a12e-48c4-94b1-401022793f12)\n\n\u003cbr/\u003e\n\n# ⚙️ 서비스 아키텍처\n\n![Streaming Data Architecture](https://github.com/user-attachments/assets/02e854c4-4512-482d-bda2-719b7ceabea6)\n\n### 🎥 호스트\n\n| **단계**                     | **설명**                                                                                                                      |\n| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |\n| **1. 방송 시작**             | 호스트는 **OBS**를 통해 방송을 시작합니다.                                                                                    |\n| **2. 스트림 전송**           | OBS에서 생성된 **RTMP 스트림**을 **RTMP 서버**로 전송합니다.                                                                  |\n| **3. 스트림 변환 및 업로드** | RTMP 서버는 스트림을 **HLS 세그먼트**(`.ts` 파일)와 **`index.m3u8`** 파일로 변환하고, 이를 **Object Storage**에 업로드합니다. |\n| **4. 방송 정보 관리**        | **API 서버**와 방송 정보를 주고받아 클라이언트 대시보드에 방송을 노출시킵니다.                                                |\n| **5. 실시간 시청**           | 클라이언트는 **Object Storage**에 직접 접근하여 **HLS 세그먼트**와 **`index.m3u8`** 파일을 통해 실시간 영상을 시청합니다.     |\n\n\u003cbr /\u003e\n\n### 💬 클라이언트\n\n| **기능**           | **설명**                                                                                           |\n| ------------------ | -------------------------------------------------------------------------------------------------- |\n| **채팅 기능**      | 호스트를 포함한 모든 클라이언트는 **채팅 서버**와 통신하여 실시간으로 채팅을 주고받을 수 있습니다. |\n| **채팅 종류**      | 채팅은 **질문**, **일반**, **공지**로 구분됩니다.                                                  |\n| **질문 채팅 처리** | **질문 채팅**은 1차적으로 **Redis**에 캐싱되며, 방송 종료 후 **MySQL**에 영구 저장됩니다.          |\n\n\u003cbr /\u003e\n\n### 🚀 CI/CD\n\n| **구성**      | **설명**                                                                                                        |\n| ------------- | --------------------------------------------------------------------------------------------------------------- |\n| **배포 도구** | **프론트엔드**와 **백엔드**는 **GitHub Actions**, **Docker**, **Docker Swarm**을 활용하여 **NCP**에 배포됩니다. |\n\n\u003cbr/\u003e\n\n# 📝 핵심 기술 정리\n프로젝트를 진행하면서 겪은 다양한 경험과 학습 내용을 꾸준히 문서화하며 지식을 공유하고, 깊이 있는 기술적 도전을 이어나가고자 합니다.\n\n## 전체\n### [📹 동영상 스트리밍 처리 프로토콜을 알아보자](https://gominzip.notion.site/b987e92eb6c84eef9af1301877eb7c91?pvs=4)\n- 처음 접하는 동영상 스트리밍 서비스의 동작 원리를 팀원들과 함께 이해하기\n- 다양한 스트리밍 프로토콜(RTMP, WebRTC, HLS 등)을 검토한 결과, 실시간 단방향 스트리밍에 적합한 RTMP와 HLS 조합으로 결정\n\n### [🚀 웹 소켓의 실시간 양방향 통신 (feat. WS vs Socket.io)](https://gominzip.notion.site/feat-WS-vs-Socket-io-13b673f3719e8037b430ff7b6af397b7?pvs=4)\n- 채팅 구현을 위해 실시간 양방향 통신 구현 방식에 대한 학습 진행\n- 생산성을 고려해 broadcast, namespace, 자동 재연결이 구현되어 있는 socket.io 라이브러리를 사용하기로 결정\n\n## 프론트엔드의 기술적 도전\n### [👷‍♀️ Shared Worker로 클라이언트의 소켓 통신 개선하기](https://gominzip.notion.site/Shared-Worker-14c673f3719e80379344fd026b1109a1?pvs=4)\n- socket.io를 통한 채팅 기능을 구현했으나, 컴포넌트 마운트 시 매번 새로운 소켓이 생성되는 이슈\n- shared worker thread를 도입해 다중 탭에서도 하나의 소켓을 공유할 수 있도록 개선\n\n### [🚨 React-Query로 안정적인 스트리밍을 위한 로딩 및 에러 관리](https://gominzip.notion.site/React-Query-04ce24ffdb68478699c61b557625a843?pvs=4)\n- HLS 영상을 받아오는 비동기 데이터 페칭에서의 에러 핸들링\n- 각각의 컴포넌트에서 로딩과 에러처리를 독립적으로 진행한 방식에서부터 AsyncBoundary를 활용하여 효율적인 비동기 데이터 페칭관리와 ErrorPage 라우팅까지 처리\n\n### [🐊 리액트 훅 폼 딥다이브](https://gominzip.notion.site/38fb796bb3034277885637e54f8747bb?pvs=4)\n- 호스트 페이지에 사용되는 많은 인풋을 리액트 훅 폼을 활용해 효율적으로 관리\n- 훅 폼의 개념과 핵심 기능을 이해하고, controlled vs uncontrolled 컴포넌트, 폼 상태 관리 최적화 및 검증 로직 구현 방법을 탐구\n\n## 백엔드의 기술적 도전\n### [☕️ NestJS를 통한 일관적인 시스템 설계](https://gominzip.notion.site/NestJS-ccb02a5403cd489ab1529799f17570b1?pvs=4)\n- 서비스 별로 분리하여 확장이 쉽고, 유지 보수에 우수한 서버를 구축하고자 계획\n- NestJS의 모듈화와 DI를 통해 각 도메인 간의 종속되지 않는 DDD 서비스 설계\n\n### [🏛️ 확장성을 고려한 초반 구조 설계](https://gominzip.notion.site/f5f09f3143bf492e87c654ecbebec9a7?pvs=4)\n- 각각의 서버가 intensive 한 부분을 고려해서 계획\n- 서버를 분리해서 확장성을 고려\n\n### [📮 채팅 서버에 Redis 를 쓴 이유](https://gominzip.notion.site/Redis-9be68c7746044d938a0dc65f9cdf47b1?pvs=4)\n- 채팅 서버가 확장될 수 있음을 고려\n- 채팅 서버 간, 데이터 공유를 위해 Redis 사용\n- Redis 도 단일로 동작하지 않도록 redis-cluster 활용\n\n### [🐬 서버를 docker swarm 으로 관리해보자](https://gominzip.notion.site/docker-swarm-80b228b59cf54d0e9221fc6c150e07bf?pvs=4)\n- 서버를 도커 컨테이너로 올려서 docker-compose 로 관리\n- docker swarm 으로 서버 인스턴스를 축소/확장할 수 있도록 관리\n\n#### [👉 더 많은 기술정리 보러 가기 👈](https://gominzip.notion.site/12d673f3719e8098ad94ed6b71b10ac0?pvs=4)\n\n\u003cbr/\u003e\n\n# 🛠️ 기술 스택\n\n| Part       | Stack                                                                                           |\n| ---------- | ----------------------------------------------------------------------------------------------- |\n| 공통       | ![Group 15](https://github.com/user-attachments/assets/82b2beac-df23-48f4-814d-b46ec79d755e)   |\n| 프론트엔드 |![Group 17](https://github.com/user-attachments/assets/9c57bf4e-df45-4319-9fb2-e5ffa58440b7)|\n| 백엔드     | ![Group 16](https://github.com/user-attachments/assets/fa4933ca-0e46-4aab-ba3d-76614c332f73)|\n\n\u003cbr/\u003e\n\n# TEAM 정권지르기 👊\n\n|                                     김준서                                     |                                     김영길                                     |                                    고민지                                     |                                    김지수                                    |                                    홍창현                                    |\n| :----------------------------------------------------------------------------: | :----------------------------------------------------------------------------: | :---------------------------------------------------------------------------: | :--------------------------------------------------------------------------: | :--------------------------------------------------------------------------: |\n| \u003cimg src=\"https://avatars.githubusercontent.com/u/45356754?v=4\" width=\"120\" /\u003e | \u003cimg src=\"https://avatars.githubusercontent.com/u/46553489?v=4\" width=\"120\" /\u003e | \u003cimg src=\"https://avatars.githubusercontent.com/u/101329724?v=4\" width=\"120\"\u003e | \u003cimg src=\"https://avatars.githubusercontent.com/u/85912592?v=4\" width=\"120\"\u003e | \u003cimg src=\"https://avatars.githubusercontent.com/u/48922050?v=4\" width=\"120\"\u003e |\n|                                     **BE**                                     |                                     **BE**                                     |                                    **FE**                                     |                                    **FE**                                    |                                    **FE**                                    |\n|                       [@i3kae](https://github.com/i3kae)                       |                    [@hoeeeeeh](https://github.com/hoeeeeeh)                    |                   [@gominzip](https://github.com/gominzip)                    |                    [@jsk3342](https://github.com/jsk3342)                    |                   [@spearStr](https://github.com/spearStr)                   |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboostcampwm-2024%2Fweb22-liboo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboostcampwm-2024%2Fweb22-liboo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboostcampwm-2024%2Fweb22-liboo/lists"}