{"id":18318697,"url":"https://github.com/connect-foundation/2019-09","last_synced_at":"2026-03-03T12:44:26.225Z","repository":{"id":35691112,"uuid":"218952027","full_name":"connect-foundation/2019-09","owner":"connect-foundation","description":"TryCatch - 레크레이션 게임 \"몸으로 말해요\"의 온라인 게임 :ok_woman: :information_desk_person: :raising_hand: ","archived":false,"fork":false,"pushed_at":"2023-07-18T23:34:26.000Z","size":7031,"stargazers_count":16,"open_issues_count":74,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-21T12:21:24.152Z","etag":null,"topics":["docker","nginx","nodejs","react","socket-io","webrtc"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/connect-foundation.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":"2019-11-01T09:09:53.000Z","updated_at":"2024-06-18T15:06:31.000Z","dependencies_parsed_at":"2024-11-05T18:11:26.650Z","dependency_job_id":"c4612a8d-9dd4-4f3f-89fe-715d548c97b4","html_url":"https://github.com/connect-foundation/2019-09","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connect-foundation%2F2019-09","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connect-foundation%2F2019-09/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connect-foundation%2F2019-09/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/connect-foundation%2F2019-09/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/connect-foundation","download_url":"https://codeload.github.com/connect-foundation/2019-09/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247406076,"owners_count":20933803,"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":["docker","nginx","nodejs","react","socket-io","webrtc"],"created_at":"2024-11-05T18:11:16.797Z","updated_at":"2026-03-03T12:44:21.185Z","avatar_url":"https://github.com/connect-foundation.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"middle\"\u003e\n  \u003cimg src=\"https://i.imgur.com/Np85GoX.png\" width=\"30%\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"middle\"\u003e\n  \u003c!----\u003e\n  \u003cimg alt=\"Version\" src=\"https://img.shields.io/badge/version-1.0.0-blue.svg?cacheSeconds=2592000\" /\u003e\n  \u003c!----\u003e\n  \u003ca href=\"https://github.com/connect-foundation/2019-09/wiki\" target=\"_blank\"\u003e\n    \u003cimg alt=\"Documentation\" src=\"https://img.shields.io/badge/documentation-yes-brightgreen.svg\" /\u003e\n  \u003c/a\u003e\n  \u003c!----\u003e\n  \u003ca href=\"https://github.com/connect-foundation/2019-09/issues\"\u003e\n    \u003cimg alt=\"issue tracking\" src=\"https://img.shields.io/github/issues/connect-foundation/2019-09\"/\u003e\n  \u003c/a\u003e\n  \u003c!----\u003e\n  \u003ca href=\"https://github.com/connect-foundation/2019-09/pulls\"\u003e\n    \u003cimg alt=\"pr tracking\" src=\"https://img.shields.io/github/issues-pr/connect-foundation/2019-09\"/\u003e\n  \u003c/a\u003e\n  \u003c!----\u003e\n  \u003ca href=\"https://github.com/connect-foundation/2019-02/blob/master/LICENSE.md\" target=\"_blank\"\u003e\n    \u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" /\u003e\n  \u003c/a\u003e\n  \u003c!----\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\n\n## 🏡 Links\n\n- **Demo** : [https://trycatch.growd.me](https://trycatch.growd.me)\n- **Documentation** : [https://github.com/connect-foundation/2019-09/wiki](https://github.com/connect-foundation/2019-09/wiki)\n\n\u003cbr\u003e\n\n## 🕺 Introduction\n\n- 🙆 💁 🙋 Try Catch는 레크레이션 게임 \u0026#34;몸으로 말해요\u0026#34;를 어디서나 즐길 수 있도록 웹으로 구현한 서비스입니다.\n\n- 네트워크 환경의 변화, 사용자의 돌발 행동에도 게임이 원활하게 진행되는 것을 목표로 합니다.\n\n- 원활한 영상 전송을, 버그 없는 게임을, 스마트폰으로도 어디서나 즐기는, 즐거운 경험을 제공하는 것을 목표로 합니다.\n\n\u003cbr\u003e\n\n## 💡 Technologies Used\n\n![](https://user-images.githubusercontent.com/30206880/71165752-c2fbaf80-2294-11ea-9025-63f9be777c5d.png)\n\n\u003cbr\u003e\n\n## 🔨 Tech Researches\n\n- [2주차-WebRTC](https://github.com/connect-foundation/2019-09/wiki/2%EC%A3%BC%EC%B0%A8-WebRTC)\n- [3주차-WebRTC로직](https://github.com/connect-foundation/2019-09/wiki/3%EC%A3%BC%EC%B0%A8-WebRTC%EB%A1%9C%EC%A7%81)\n- [4주차-WebRTC로직](https://github.com/connect-foundation/2019-09/wiki/4%EC%A3%BC%EC%B0%A8-%EC%A4%91%EA%B0%84%EB%B0%9C%ED%91%9C)\n- [5주차-websocket/redis/pm2](https://github.com/connect-foundation/2019-09/wiki/5%EC%A3%BC%EC%B0%A8-%EA%B8%B0%EC%88%A0%EA%B3%B5%EC%9C%A0%EC%9E%90%EB%A3%8C-socket.io,-pm2,-redis)\n- [6주차-custom hook](https://github.com/connect-foundation/2019-09/wiki/6%EC%A3%BC%EC%B0%A8-%EA%B8%B0%EC%88%A0%EA%B3%B5%EC%9C%A0%EC%9E%90%EB%A3%8C-Custom-Hook)\n- [7주차-실시간 게임에서 유저 이탈 상황 처리하기](https://github.com/connect-foundation/2019-09/wiki/7%EC%A3%BC%EC%B0%A8-%EC%8B%A4%EC%8B%9C%EA%B0%84-%EA%B2%8C%EC%9E%84%EC%97%90%EC%84%9C-%EC%9C%A0%EC%A0%80-%EC%9D%B4%ED%83%88-%EC%83%81%ED%99%A9-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0)\n\n\u003cbr\u003e\n\n## :hammer_and_wrench: Process\n\n### Sprint 1\n\n- 어떻게 하면 `도전적인 주제`를 선정할 것인가?\n  - \u003cb\u003e도전적인 기술\u003c/b\u003e : 우리가 아직 `경험해보지 못한 기술`\n    - \u003cb\u003e영상\u003c/b\u003e : 멤버십 기간에 한번도 경험해보지 못한, 도전적인 주제\n    - \u003cb\u003e게임\u003c/b\u003e : 마찬가지로 경험해보지 못한 새로운 주제\n  - \u003cb\u003e결론\u003c/b\u003e : `영상 + 게임` 두 주제를 결합해서 지금까지 경험해보지 못한 기술에 `도전`해보자.\n\n### Sprint 2\n\n- WebRTC\n  - 이 기술이 `가능한 기술`인가? 또한 이 `기술의 원리`는 무엇인가?\n    - `Relaying`, `Connection reversal`, `UDP hole punching` 과 같은 `P2P 구현 기술`에 대한 공부\n    - P2P 연결은 이미 존재하는 기술이고, 이 기술을 적용하면 충분히 실현이 가능하리라는 확신\n    - `WebRTC`는 존재하는 기술을 적용하지만 `브라우저`에서 실현이 가능하다는 점에서 획기적인 기술\n  - STUN 서버 : `사용자의 IP`를 알려주는 서버\n  - TURN 서버 : P2P 연결이 실패할 경우, `우회하여 연결`하는 서버\n  - 이해를 기반으로 `N:N 다자간 연결` 구현\n- 환경 세팅\n  - docker : `버전 관리`와 OS로부터 `독립적인 환경` 제공\n  - HTTPS : 브라우저로부터 `카메라 권한`을 얻기 위한 HTTPS 인증\n\n### Sprint 3\n\n- Client React App 개발 시작\n\n  - 모바일 뷰(responsive) 지원 결정\n  - client 프로젝트 구성방법 회의/결정\n  - component(가장 작은 컴포넌트), container(몇개의 가장 작은 컴포넌트의 집합으로 이루어진 컴포넌트), page(component와 container의 집합으로 route와 묶이는 실제적 페이지 컴포넌트)로 구성\n  - material-ui 필요여부결정 및 적용\n  - 메인페이지(component, container, page) 구현\n\n- `1:N`다자간 통신\n  - 기존 WebRTC에서는 클라이언트 전원의 `N:N` 연결\n  - `불필요한 연결`이 발생하는 문제\n  - `Streamer(영상 송출자)`와 `Viewer(영상 수신자)` 간의 `1:N` 연결 고안 및 변경\n- 게임 룸 구현\n  - socket.io 활용\n    - socket.io API에서 제공하는 room 활용\n  - 게임 이벤트 처리에 대한 로직 구현\n  - 한 세트(스트리머 전환 x) 게임 진행\n\n### Sprint 4\n\n- React\n\n  - 게임페이지(component, container, page) 구현\n  - 글로벌 상태와 reducer를 이용한 dispatch 구현\n  - 채팅 컴포넌트 구현 및 위의 dispatch 적용\n\n- 프론트엔드 WebRTC 리팩토링\n  - 기존의 코드 : \u003cb\u003esocket의 기능이 WebRTC에 종속적인 구조\u003c/b\u003e\n    - 채팅이나 게임 이벤트를 확장할 수 없는 구조\n  - `ClientManager`, `ChattingManager`, `StreamingManager`로 클라이언트의 매니저 분리\n    - 각각의 매니저가 소켓 객체를 공유하지만 담당하는 부분 분리\n    - 기능 확장 용이 및 책임 분산 가능\n\n### Sprint 5\n\n- React\n\n  - 랭킹페이지(component, container, page) 구현\n  - 모바일 뷰 최적화를 위한 리팩토링\n  - 게임뷰에서 필요한 여러 notice 컴포넌트 구현\n  - - 큰 페이지 컴포넌트인 Game 리팩토링\n    - presenter(jsx), index(logic), style(style)로 파일 분리\n\n- 게임 진행 시스템 구성\n  - 게임 룸에 waiting, playing 등의 `status 설정`\n  - 1라운드(모든 플레이어가 돌아가면서 게임) 진행 구성\n    - 기존에는 1명의 플레이어만 영상 송출이 가능했었음\n\n### Sprint 6\n\n- React\n\n  - 글로벌 상태와 dispatch action을 action creator 형태로 리팩토링\n  - 큰 페이지 컴포넌트인 Game 리팩토링\n    - 로직을 hook으로 분리\n\n- 게임 진행 오류 수정\n  - `Sprint 5`에 진행한 버그데이에 발생한 문제 해결\n    - 카메라 권한 거부에 대한 예외 처리\n    - 게임 중간에 플레이어가 나갈 경우에 대한 예외 처리\n  - 팀원 전원의 테스팅을 통해 발생하는 오류 제거\n\n### Sprint 7\n\n- React\n\n  - Rules of Hooks 권고사항 반영\n  - jest warning 해결\n  - 컴포넌트가 아닌 곳에서 쓰이는 hook 상위 컴포넌트로 이동\n\n- 리팩토링\n  - 클라이언트와 서버에 존재하는 `Magic Number` 제거\n\n\u003cbr\u003e\n\n## 🚌 Data Transfer\n\n### [**WebRTC**](https://webrtc.org/)\n\n#### Peer To Peer로 전송하는 영상 스트리밍\n\n- 서버를 통한 스트리밍 비용을 최소화하기 위해 클라이언트 간의 연결을 활용하는 `WebRTC` 기술을 선택하였습니다.\n\n### [**Socket.io**](socket.io)\n\n#### Socket통신을 통한 게임 시스템 구현\n\n- `WebRTC`의 메타데이터 전송과 게임에서 실시간으로 발생하는 이벤트를 처리하기 위해 `socket.io`를 사용했습니다.\n\n- [**게임 이벤트 흐름**](https://github.com/connect-foundation/2019-09/wiki/%EA%B2%8C%EC%9E%84-%EC%8B%9C%EB%82%98%EB%A6%AC%EC%98%A4-%EC%9D%B4%EB%B2%A4%ED%8A%B8)\n\n  - **Join and Waiting status**\n    \u003cbr\u003e\n\n    ![Join and Waiting Status (1)](https://user-images.githubusercontent.com/30206880/71319293-9091c280-24df-11ea-9154-49fe2d94a352.png)\n\n  - **Connecting status**\n    \u003cbr\u003e\n\n    ![connecting (1)](https://user-images.githubusercontent.com/30206880/71319295-94254980-24df-11ea-85f2-efbf999b6011.png)\n\n  - **Initializing status**\n    \u003cbr\u003e\n\n    ![initializing](https://user-images.githubusercontent.com/30206880/71322360-1aef1c00-250a-11ea-80f7-236347c9e5ac.png)\n\n  - **Playing status**\n    \u003cbr\u003e\n\n    ![playing (1)](https://user-images.githubusercontent.com/30206880/71319297-9b4c5780-24df-11ea-8e9c-96e7fde3427b.png)\n\n  - **Scoring status and end game**\n    \u003cbr\u003e\n\n    ![scoringAndEndGame (1)](https://user-images.githubusercontent.com/30206880/71322301-8be20400-2509-11ea-9559-b812aa305b1e.png)\n\n## 🌊 Data flow\n\n![](https://user-images.githubusercontent.com/30206880/71165116-a14df880-2293-11ea-8e90-f3f23e1c128f.png)\n\n\u003cbr\u003e\n\n## 🚴 How To Run\n\n\u003e [docker](https://www.docker.com/)와 [docker-compose](https://docs.docker.com/compose/)의 설치를 필요로 합니다.\n\n```sh\n$ docker-compose up -d\n```\n\n\u003cbr\u003e\n\n## 🎬 Demo video\n\n#### 7주차 데모\n[Youtube](https://www.youtube.com/watch?v=lg8UKEs0g90)\n\n#### 4주차 데모\n\n\u003cimg src=\"https://i.imgur.com/OpWe8nt.gif\" width=\"40%\"/\u003e\n\n#### 2주차 데모\n\n\u003cimg src=\"https://i.imgur.com/EwBnzHG.gif\" width=\"40%\"/\u003e\n\n\u003cbr\u003e\n\n## ✍️ Author\n\n**Team Try Catch**\n\n- **권기웅** [(mosball)](https://github.com/mosball)\n- **나영균** [(younguna)](https://github.com/younguna)\n- **장기원** [(OriginJang)](https://github.com/OriginJang)\n- **조정현** [(JeonghyunJo)](https://github.com/JeonghyeonJo)\n\n\u003cbr\u003e\n\n## 🔥 Issues\n\n- [link](https://github.com/connect-foundation/2019-09/issues)\n\n\u003cbr\u003e\n\n## 📜 License\n\nCopyright © Try Catch\n[MIT License](https://opensource.org/licenses/MIT)\n\n\u003cbr\u003e\n\n## :octocat: Show your support\n\nGive a ⭐️ if this project helped you!\n\n---\n\n#### Special Thanks to [Boostcamp](http://boostcamp.connect.or.kr/) and [Connect Foundation](https://connect.or.kr/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnect-foundation%2F2019-09","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconnect-foundation%2F2019-09","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconnect-foundation%2F2019-09/lists"}