본문 바로가기

블로그 / 기술

빠른 매칭 15초와 친구방 4자리 코드, 랜선포차의 방 찾기 구조

랜선포차의 방 찾기는 열린 방 하나에 사람을 모으는 빠른 매칭과, 헷갈리는 글자를 뺀 4자리 코드로 들어가는 친구방 두 갈래다. 15초 대기, 32글자 코드, 재접속 복귀를 코드 기준으로 정리했다.

Salmonholic ·· 5분 읽기

랜선포차 홈 화면의 빠른 매칭 버튼과 친구방의 4자리 방 코드 DLVH 화면

랜선포차는 폰 브라우저에서 여섯 명이 한 방에 모여 미니게임을 하는 파티 게임이다. 여섯 명이 모여야 시작하는 게임에서 가장 먼저 부딪히는 문제는 “어떻게 모으나”다. 나는 1인 개발자이고 서버는 서울에 있는 작은 VM 한 대다. 그래서 매칭도 거창한 대기열 대신 최대한 단순한 두 갈래로 만들었다. 모르는 사람과 바로 하는 빠른 매칭, 아는 사람끼리 코드로 모이는 친구방이다.

두 갈래 모두 9월 26일 밤, 서버 코어와 미니게임 5종을 처음 올린 커밋(e5ee069)에 같이 들어갔다. 매칭을 맡는 클래스는 주석까지 합쳐 108줄이다.

빠른 매칭: 열린 방은 언제나 하나

빠른 매칭의 규칙은 한 문장이다. 지금 사람을 받고 있는 방이 있으면 거기로, 없으면 새로 만든다. 서버는 “열린 빠른 매칭 방”을 딱 하나만 기억한다. 누가 빠른 매칭을 누르면 그 방에 앉히고, 그 방이 시작되는 순간 기억을 지운다. 다음 사람은 새 방을 연다.

항목 값
한 방 좌석 6
첫 사람이 들어온 뒤 대기 15초
여섯 자리가 다 차면 대기 없이 바로 시작
대기 중 사람이 다 나가면 타이머 취소, 방 정리
서버가 방을 더 열 수 없으면 “만석” 안내

동시 접속자가 적은 초기 게임에서 가장 나쁜 경험은 “매칭 중…“만 보다가 창을 닫는 것이다. 그래서 대기 시간을 15초로 못 박았다. 매칭 품질(실력, 지역)을 따지는 대신 15초 안에는 무조건 시작한다를 택했다. 서버가 서울 한 곳뿐이라 지역을 나눌 이유도 없었다.

빠른 매칭 대기 화면. 내 칸만 차 있고 나머지 다섯 칸은 연결 중으로 보인다 빠른 매칭 대기실. 위쪽에 “들어오는 중 1/6”이 뜨고, 빈 칸은 “연결 중..“으로 보인다.

대기실은 여섯 칸짜리 화상 채팅 화면을 그대로 쓴다. 내 칸만 먼저 켜지고, 나머지 칸은 “연결 중..“으로 남아 있다가 들어오는 순서대로 캐릭터가 앉는다. 위쪽 숫자는 “들어오는 중 n/6”이다. 기다리는 동안 할 일이 없으면 15초도 길게 느껴지기 때문에, 대기실에서도 채팅과 이모티콘은 그대로 쓸 수 있다.

서버가 받을 수 있는 양에도 선을 그었다. 동시에 열 수 있는 방은 기본 500개, 웹소켓 연결은 기본 3,000개다. 둘 중 하나라도 넘으면 새 방을 만들지 않고 “포차가 만석입니다. 잠시 후 다시 시도해 주세요.“를 돌려준다. 작은 VM 한 대가 버틸 수 있는 선 밖으로 나가서 이미 하고 있던 판까지 느려지는 것보다, 새로 오는 사람에게 잠시 기다려 달라고 하는 편이 낫다고 봤다.

친구방: 헷갈리는 글자를 뺀 32글자

친구방은 방을 만든 사람에게 4자리 코드를 준다. 코드는 영문 대문자와 숫자에서 I, O, 0, 1을 뺀 32글자로 만든다. 폰 화면으로 코드를 불러 줄 때 “아이인가요 일인가요”, “오인가요 영인가요”가 나오지 않게 하려는 것이다.

항목 값
사용 글자 ABCDEFGHJKLMNPQRSTUVWXYZ23456789 (32자)
길이 4자리
가능한 코드 수 32⁴ = 1,048,576
중복 처리 이미 쓰는 코드면 다시 뽑기
입력 정리 앞뒤 공백 제거, 대문자로 변환
코드 수명 방이 비면 코드도 반납

32글자 × 4자리면 백만 개가 넘는다. 동시에 열리는 방 수에 비하면 겹칠 확률은 작지만, 겹치면 다시 뽑는 반복문 하나로 끝냈다. 입력 쪽도 같은 글자표를 쓴다. 홈 화면의 코드 입력칸은 소문자를 대문자로 바꾸고, 32글자 밖의 글자는 쳐도 지워지고, 네 글자가 차야 “입장” 버튼이 켜진다. 서버와 클라이언트의 글자표가 다르면 “분명 맞게 쳤는데 없는 방”이 되기 때문에, 클라이언트 코드에 “서버와 같다”는 주석을 붙여 두었다.

코드를 불러 주는 대신 링크로 보낼 수도 있다. 대기실의 공유 버튼을 누르면 폰의 공유 시트가 열리고, 방 코드와 ?room=코드가 붙은 주소가 함께 담긴다. 공유 시트를 쓸 수 없는 브라우저에서는 같은 문구를 클립보드에 복사하고 “초대 문구 복사됨. 단톡방에 붙여넣기”를 띄운다. 링크를 받은 사람은 주소를 여는 것만으로 코드 입력 없이 그 방으로 들어간다. 복사가 막힌 환경이면 “복사가 막혔어요. 코드를 불러 주세요”라고 알려 준다.

친구방 화면. 방 코드 DLVH와 친구 부르기 버튼, 방장 표시, 시작하기 버튼 친구방. 코드를 누르면 복사되고, 방장만 “시작하기”를 누를 수 있다.

친구방은 빠른 매칭과 달리 자동으로 시작하지 않는다. 처음 들어온 사람이 방장이 되고, 방장이 “시작하기”를 눌러야 판이 열린다. 친구가 다 모일 때까지 기다릴지, 몇 명이 모였을 때 시작할지는 방장이 정한다. 방장이 대기실에서 나가면 남아 있는 사람 중 다음 사람이 방장이 된다.

판이 끝나면 방장은 “한 판 더”로 같은 멤버와 다시 할 수 있다. 연결이 남아 있는 사람만 자리를 유지하고, 배탈 게이지와 라운드는 처음으로 돌아간다. 빠른 매칭으로 만난 사람들과 계속 하고 싶을 때를 위해, 결과 화면에서 바로 친구방을 만드는 버튼도 붙였다(7613232).

재접속: 모드보다 “진행 중인 자리”가 먼저

모바일 브라우저는 연결이 자주 끊긴다. 지하철에서 터널에 들어가거나, 메신저 알림을 보러 앱을 잠깐 바꾸기만 해도 웹소켓이 닫힌다. 그래서 서버는 새 연결이 오면 모드(빠른 매칭, 방 만들기, 코드 입장)를 보기 전에 이 계정이 앉아 있는 진행 중인 방이 있는지부터 찾는다.

  1. 진행 중인 방에 이 계정의 자리가 있으면, 모드와 상관없이 그 자리로 돌려보낸다.
  2. 끊기기 전의 자리로 돌아간다. 배탈 게이지와 캐릭터는 그대로다.
  3. 이미 끝난 판(결과 화면)은 찾지 않는다. 그래야 “다시 하기”를 눌렀을 때 새 방으로 간다.
  4. 이어하기로 들어왔는데 방이 이미 없으면 “우유 파티가 이미 파했어요”를 보여 준다.

같은 계정으로 연결이 두 개 생기면 먼저 연결을 닫는다. 폰에서 탭을 두 개 열었을 때 한 자리에 두 사람이 앉는 일을 막으려는 것이다.

단순하게 남겨 둔 것들

지금 구조에는 없는 것도 많다. 실력별 매칭, 친구 목록, 초대 링크 푸시 같은 것은 만들지 않았다. 동시 접속자가 많지 않은 지금은 “15초 안에 시작”과 “코드 4자리”가 대부분의 상황을 해결한다. 대신 매칭 클래스는 런타임과 분리해 두어서, 나중에 서버를 다른 구조로 옮기면 이 클래스가 매칭 인스턴스, 방 클래스가 방 인스턴스가 되도록 주석으로 적어 두었다.

코드를 친구에게 불러 주는 것부터가 게임의 일부라고 생각한다. 랜선포차 게임 페이지에서 친구방을 열어 보고, 방에 모인 뒤 무슨 일이 벌어지는지는 배탈 게이지와 화장실 관전 설계 글에 이어서 적었다.

#랜선포차#매칭#멀티플레이#웹소켓#서버 설계

함께 읽으면 좋은 글

전체 글 →