【제32회】 방장(호스트)이 자리를 비워도 해산되지 않게! P2P 채팅 관리 권한 자동 선출 및 호스트 강탈 기능
요약
본 글은 P2P 채팅 시스템에서 호스트(방장)가 이탈했을 때 발생하는 관리 공백 문제를 해결하는 방법을 다룹니다. IRC의 운영자 권한(/OP) 개념을 WebRTC에 적용하여, 참여자가 원클릭으로 다른 사용자에게 관리 권한을 '강탈'할 수 있는 기능을 구현했습니다.
핵심 포인트
- 호스트 이탈 시 방 관리 기능 상실 문제를 해결함.
- 참여자가 다른 사용자에게 관리 권한(Operator)을 강탈 가능하게 함.
- 권한 이양 시 UI 및 시스템 메시지 변화를 즉시 반영함.
- 서버 측에서 호스트 권한 사칭/탈취를 엄격히 검증함.
안녕하세요! 2채널 호환 게시판 시스템 「츠우바이채널(つゔぁいちゃんねる, 2ch.biz)」 개발 기록 제32회입니다.
지난번(제31회)에는 서버에 로그가 없는 환경에서도 참여자가 자연스럽게 대화에 합류할 수 있는 「P2P 분산 과거 로그 동기화」를 구현했습니다.
채팅이 활발해지고 밤새도록 이야기하는 사용자가 늘어나면서, 다음으로 커뮤니티 내에서 빈번하게 발생한 문제가 바로 **「방장(호스트)의 잠수/이탈 문제」**입니다.
'내일 출근해야 하니까 이제 잘게 ノ시'라며 방장이 브라우저를 닫는 순간, 승인제 룸에 새로운 사람이 들어올 수 없게 되거나, 트롤을 강퇴할 수 있는 사람이 사라져 버립니다.
본고에서는 IRC(Internet Relay Chat)의 전통적인 /OP (운영자 권한 부여) 사상을 현대의 WebRTC에 이식하여, 호스트가 퇴실하기 전에 다른 참여자에게 관리 권한을 원클릭으로 넘겨주는 「호스트 강탈 기능(수동 권한 이양)」 구현을 설명합니다!
저희 P2P 채팅에서 방을 개설한 초대 호스트(Host)에게는 다음과 같은 중요한 관리 권한이 집중되어 있습니다.
-
입실 요청의 승인/거부: 비밀번호제나 초대제(허가제) 룸에서는, 입실 희망자가 오면 호스트 화면에 '승인 대기 리퀘스트'가 팝업되며, 호스트가 '허용'을 누르지 않으면 입장할 수 없습니다.
-
불량 사용자 강퇴: 룸 내에서 욕설을 하는 트롤을 방에서 추방하는 권한을 가집니다.
-
토픽(게시판) 변경: 방의 제목이나 의제를 업데이트할 수 있습니다.
하지만 개인 간의 P2P 통신이다 보니, **「호스트가 브라우저를 닫으면, 방 관리자가 제로가 된다」**는 치명적인 구조적 과제를 안고 있었습니다.
【기존의 비극】
호스트 Alice: '다들 즐거운데, 나 이제 졸리니까 잘게~'
참여자 Bob: '잘 자!'
...
이 문제를 해결하기 위해, 호스트가 퇴실하기 전에 참여자 목록 중에서 신뢰할 수 있는 누군가(혹은 그 자리에 있는 누구라도)를 선택하여 관리 권한을 원터치로 강탈할 수 있는 **「호스트 강탈 기능」**을 도입했습니다.
기술적인 권한 전환은 물론, 2채널다운 '분위기'와 한눈에 알 수 있는 UI의 즉시 반영에 공들였습니다.
호스트로 로그인한 경우, 오른쪽 닉네임 목록의 각 참여자 우측 끝에 '👑(이양)'과 '×(강퇴)' 액션 버튼이 나타납니다 (자신에게는 표시되지 않습니다).
'👑' 버튼을 누르면, 일부러 다소 가벼운 확인 대화 상자가 나타납니다.
'사용자명'에게 관리 권한(호스트)을 이양(강탈)하시겠습니까?
권한 이양이 이루어지면, 방의 모든 참여자 로그 화면에 IRC 오마주 시스템 메시지가 흐릅니다.
* Alice가 Bob에게 관리 권한을 이양했습니다 (IRC /OP)
새 호스트로 선택된 사용자(Bob)의 화면에서는, 페이지를 새로고침할 필요 없이 즉시 다음과 같은 변화가 일어납니다:
- 토픽 바 배지가
👤 일반 참여자에서👑 Operator로 점등. - 보류되었던 '입실 승인 대기 섹션'이 스르륵 슬라이드 인 표시됨.
- 다른 모든 참여자 옆에 '👑'와 '×' 조작 버튼이 활성화됩니다.
시그널링 서버 측에서는, 비정상적인 클라이언트가 임의로 호스트 권한을 사칭하거나 탈취하지 못하도록 엄격한 검증을 수행합니다.
// server.js: 호스트 권한 이양 핸들러
function handleTransferHost(room, senderId, targetPeerId) {
// 1. 전송자가 현재의 공식 호스트인지 검증
...
클라이언트 측에서는, 시그널링을 통해 host_changed 이벤트를 수신하는 순간 자신의 상태를 업데이트하여 UI를 재렌더링합니다.
// 이벤트 수신 핸들러
function onHostChanged(event) {
const isMeNewHost = (event.newHostId === myPeerId);
...
자동 검증 스크립트 및 실기 브라우저의 멀티 윈도우 테스트를 통해 다음과 같은 동작을 확인했습니다.
- 권한 탈취 공격 방지: 일반 참여자로부터
transfer_hostAPI를 위장 전송해도,403 Forbidden으로 확실하게 차단됨을 확인했습니다.
일반 참가자부터
끊김 없는 경험: Alice가 Bob에게 붙여넣기(나すりつけ)를 한 직후 Alice가 브라우저를 닫아도 방이 전혀 해산되지 않고, Bob을 중심으로 채팅이 평온하게 지속되는 것을 확인했습니다.
사용자 반응: '붙여넣기 기능 대박', '이거면 안심하고 잠들 수 있겠다', '갑자기 왕관 생겨서 깜짝 놀랐지만 재미있었다ㅋㅋ' 등, 실용성과 커뮤니티의 유쾌함이 결합된 큰 호응을 얻은 기능입니다.
호스트가 자리를 비워도 채팅이 이어질 수 있게 되면서, P2P 채팅은 밤새도록 이야기를 나눌 수 있는 커뮤니티의 '아지트'로 진화했습니다.
하지만 장시간 채팅에서는 필연적으로 **'이미지나 대용량 파일 공유'**가 발생합니다.
WebRTC DataChannel을 통해 이미지나 zip 파일을 공유할 때, 모든 사람의 브라우저에 무조건 메가바이트급 바이너리를 일제히 브로드캐스트하게 되면, **'스마트폰 데이터(기가)가 바닥난다!', '통신이 멈췄다!'**라는 비명이 터져 나오게 됩니다.
필요한 사람만 안전하고 수동으로 다운로드할 수 있는 '온디맨드 전송'을 어떻게 구현했을까요?
실제 서비스: https://2ch.biz/
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기