PeerJS로 WebRTC 길들이기: 간단한 P2P 웹 게임 만들기
게시 됨: 2022-03-11WebRTC는 웹 브라우저 간의 실시간 통신을 가능하게 하는 기술입니다. 이는 비교적 새로운 것이며 API 정의는 여전히 초안으로 간주됩니다. WebRTC가 아직 모든 주요 웹 브라우저에서 지원되지 않는다는 사실과(그리고 지원하는 브라우저 중 일부는 이 기술의 모든 기능을 지원하지 않음) 미션 크리티컬 애플리케이션에 WebRTC를 사용하기가 상대적으로 어렵습니다. . 또는 그렇게 생각할 것입니다!
WebRTC는 2011년 5월 Google에서 처음 소개된 이후로 많은 최신 웹 애플리케이션에서 사용되었습니다. 많은 최신 웹 브라우저의 핵심 기능인 웹 애플리케이션은 이 기술을 원활하게 활용하여 다양한 방식으로 향상된 사용자 경험을 제공할 수 있습니다. 부풀려진 브라우저 플러그인이 필요하지 않고 P2P(피어 투 피어) 네트워크를 활용할 수 있는 비디오 스트리밍 또는 회의 응용 프로그램(일부 서버를 통해 모든 데이터 비트를 전송하지 않음)은 모든 놀라운 것들의 일부일 뿐입니다. WebRTC로 달성할 수 있습니다.
이 기사에서는 WebRTC를 사용하여 Connect Four의 간단한 P2P 웹 게임을 만드는 방법을 살펴보겠습니다. WebRTC의 다양한 거친 가장자리와 구현 차이점을 해결하기 위해 놀라운 JavaScript 라이브러리인 PeerJS를 사용합니다.
WebRTC를 통한 데이터
시작하기 전에 WebRTC가 오디오 및 비디오 스트림을 전송하는 것이 전부는 아니라는 점을 이해하는 것이 중요합니다. 또한 P2P 데이터 채널을 지원합니다. 이러한 채널은 신뢰할 수 있는 것과 신뢰할 수 없는 것의 두 가지 변형으로 제공됩니다. 짐작할 수 있듯이 신뢰할 수 있는 데이터 채널은 메시지가 순서대로 전달되고 전달되도록 보장하지만 신뢰할 수 없는 채널은 그러한 보장을 제공하지 않습니다.
또한 WebRTC 데이터 채널은 일반적인 WebRTC 피어 연결에 필요한 것 외에는 특별한 인프라 설정이 필요하지 않습니다. 피어 간의 연결을 조정하기 위한 시그널링 서버, 피어의 공개 ID를 파악하기 위한 STUN 서버, 선택적으로 TURN 서버 피어 간의 직접 연결을 설정할 수 없는 경우(예: 두 피어가 NAT 뒤에 있는 경우) 피어 간에 메시지를 라우팅합니다. 이러한 두문자어가 친숙하게 들린다면 WebRTC는 가능한 한 기존 기술의 용도를 변경하기 때문입니다.
이것은 멀티플레이어 게임, 콘텐츠 전달, 파일 공유를 포함하되 이에 국한되지 않는 WebRTC의 훨씬 더 많은 사용 사례의 문을 엽니다. 다시 말하지만, 모든 중개 서버가 필요하지 않으므로 대기 시간이 짧습니다.
우리의 간단한 웹 게임에서는 두 웹 브라우저 사이의 데이터 채널을 사용하여 앞뒤로 플레이어의 움직임을 전달합니다.
PeerJS를 만나보세요
PeerJS는 브라우저에서 WebRTC를 구현하고 이를 중심으로 간단하고 일관되며 우아한 API를 래핑합니다. 이전 브라우저의 WebRTC 구현에서 다양한 구멍을 막습니다. 예를 들어 Chrome 30 이상에서는 신뢰할 수 없는 데이터 채널만 사용할 수 있었습니다. PeerJS는 신뢰할 수 있는 데이터 채널을 사용하도록 구성된 경우 이전 브라우저에 shim을 사용합니다. 이것은 안정적인 채널의 기본 구현만큼 성능이 좋지는 않지만 여전히 작동합니다.
PeerJS를 사용하면 피어를 식별하는 것이 훨씬 더 간단합니다. 모든 피어는 ID만 사용하여 식별됩니다. 피어가 스스로 선택하거나 서버가 생성하도록 할 수 있는 문자열입니다. WebRTC는 P2P 통신을 약속하지만 연결 브로커 역할을 하고 신호를 처리하려면 여전히 서버가 필요합니다. PeerJS는 클라우드 호스팅 버전(현재 무료이며 몇 가지 제한 사항이 있음)을 사용하지 않으려는 경우 이 연결 브로커 서버 PeerJS 서버(Node.js로 작성)의 오픈 소스 구현을 제공합니다.
4개 연결 P2P
이제 WebRTC, 즉 PeerJS로 작업할 수 있는 자신감을 얻었으므로 간단한 Node.js/Express 응용 프로그램을 만드는 것으로 시작하겠습니다.
npm init npm install express --save npm install jade --save npm install peer --save
우리는 이것을 PeerJS Server를 호스팅하고 페이지와 프런트 엔드 자산을 제공하는 데만 사용할 것입니다. 단일 페이지만 제공하면 되며 여기에는 일반 메인 메뉴와 7x6 Connect Four 그리드의 두 섹션이 포함됩니다.
PeerJS 서버
자체 PeerJS 서버를 호스팅하는 것은 정말 쉽습니다. GitHub의 공식 리포지토리에는 PeerJS Server 인스턴스를 Heroku에 배포할 수 있는 원클릭 버튼도 있습니다.
우리의 경우 Node.js 애플리케이션에서 ExpressPeerServer 의 인스턴스를 만들고 "/peerjs"에서 제공하려고 합니다.
var express = require('express') var app = express() // … Configure Express, and register necessary route handlers srv = app.listen(process.env.PORT) app.use('/peerjs', require('peer').ExpressPeerServer(srv, { debug: true }))
PeerJS 클라이언트
PeerJS 서버를 실행하고 클라이언트 측으로 이동합니다. 앞서 논의한 바와 같이 PeerJS는 고유 ID를 가진 피어를 식별합니다. 이러한 ID는 PeerServer에서 모든 피어에 대해 자동으로 생성하거나 Peer 개체를 인스턴스화하는 동안 모든 피어에 대해 하나를 선택할 수 있습니다.
var peer = new Peer(id, options)
여기서 서버가 우리를 위해 하나를 생성하도록 하려면 id 를 모두 생략할 수 있습니다. 우리의 경우 그것이 우리가하고 싶은 것입니다. PeerServer는 제공하는 ID가 고유한지 확인합니다. 두 번째 인수인 options 는 일반적으로 키 (클라우드 호스팅 PeerServer를 사용하는 경우 API 키 또는 PeerServer를 직접 호스팅하는 경우 host , port , path 등)를 포함하는 객체입니다.
var peer = new Peer({ host: location.hostname, port: location.port || (location.protocol === 'https:' ? 443 : 80), path: '/peerjs' })
두 PeerJS 피어 간에 연결을 설정하려면 피어 중 하나가 다른 피어의 ID를 알아야 합니다. 일을 단순하게 유지하기 위해 WebRTC를 통한 Connect Four 구현에서는 게임을 시작하는 플레이어가 자신의 피어 ID를 상대방과 공유하도록 요구할 것입니다. 목적지 피어 ID를 알고 있으면 peer.connect(destId) 에 대한 간단한 호출만 있으면 됩니다.
var conn = peer.connect(destId)
peer.connect(destId) 가 반환하는 Peer 객체와 DataConnection 객체는 모두 들을 가치가 있는 정말 유용한 이벤트를 내보냅니다. 이 자습서의 목적을 위해 DataConnection 개체의 'data' 이벤트와 두 개체의 'error' 이벤트에 특히 관심이 있습니다.

연결의 다른 쪽 끝으로 데이터를 보내 려면 conn.send(data) 를 호출하기만 하면 됩니다.
conn.send('hello')
여기서 우리의 요구 사항에 대해서는 약간 과잉이지만 PeerJS는 BinaryPack 형식으로 인코딩한 후 피어 간에 데이터를 전송합니다. 이를 통해 피어는 문자열, 숫자, 배열, 개체 및 Blob까지 통신할 수 있습니다.
들어오는 데이터를 수신하려면 conn 에서 'data' 이벤트를 수신하기만 하면 됩니다.
conn.on('data', function(data) { // data === 'hello' })
그리고 그것이 우리에게 필요한 전부입니다!
게임 로직
게임을 시작하는 첫 번째 플레이어에게는 PeerJS에서 생성한 피어 ID가 표시되며 이 ID는 상대방과 공유할 수 있습니다. 상대방이 첫 번째 플레이어의 피어 ID를 사용하여 게임에 참가하면 첫 번째 플레이어가 이동할 수 있습니다.
간단한 규칙과 메커니즘의 게임인 Connect Four에는 한 가지 유형의 이동만 있습니다. 각 플레이어는 차례로 열을 선택하고 디스크를 그 안에 넣어야 합니다. 이것은 피어가 통신해야 하는 모든 것이 현재 플레이어가 디스크를 넣기로 선택한 열 번호라는 것을 의미합니다. 우리는 이 정보를 문자열 '이동'과 숫자 - 0-의 두 가지 요소가 있는 배열로 전송할 것입니다. 왼쪽부터 열의 기반 인덱스입니다.
플레이어가 열을 클릭할 때마다:
if(!turn) { // it is not the current player's turn return } var i // i = chosen column index if(grid[i].length == 6) { // the column doesn't have any more space available return } // track player's move locally grid[i].push(peerId) // end current player's turn turn = false conn.send(['move', i])
이 이동 데이터를 상대방에게 보낸 후 게임의 상태를 로컬로 업데이트합니다. 여기에는 현재 플레이어가 이겼는지 또는 게임이 무승부로 종료되었는지 결정하는 것이 포함됩니다.
이 이동 데이터의 수신 측에서:
if(turn) { // ignore incoming move data when it is the current player's turn return } var i = data[1] if(grid[i].length == 6) { // ignore incoming move data when it is invalid return } // track opponent's move locally grid[i].push(opponent.peerId) // activate current player's turn turn = true
그리고 자연스럽게 게임의 상태를 로컬로 업데이트하고 상대방이 이겼는지 또는 게임이 무승부로 종료되었는지 확인합니다.
들어오는 데이터에 대해 온전성 검사를 수행해야 하는 방법에 주목하십시오. WebRTC 기반 게임에는 이동 데이터를 검증하는 중개 서버 및 서버 기반 게임 로직이 없기 때문에 이것은 중요합니다.
스니펫을 단순하게 유지하기 위해 UI를 업데이트하는 코드 행은 생략되었습니다. 여기에서 클라이언트 측 JavaScript의 전체 소스 코드를 찾을 수 있습니다.
모든 것을 연결
이 모든 것을 결합하기 위해 두 섹션이 있는 간단한 페이지를 만듭니다. 페이지 로드 시 주 메뉴가 포함된 섹션이 표시되고 게임 그리드가 포함된 섹션은 숨겨진 상태로 유지됩니다.
section#menu div.animated.bounceIn div h1 Connect Four br div.no-support() div.alert.alert-warning p Unfortunately, your web browser does not <a href="http://iswebrtcreadyyet.com">support WebRTC</a> div a.btn.btn-primary.btn-lg(href='#start') Start | a.btn.btn-default.btn-lg(href='#join') Join section#game() div div h1 Connect Four br table.table.grid tbody for i in [0, 1, 2, 3, 4, 5] tr for j in [0, 1, 2, 3, 4, 5, 6] td div.slot br div.alert.alert-info p
이러한 DOM 요소를 보기 좋게 만드는 것은 이 튜토리얼의 범위를 벗어납니다. 따라서 우리는 신뢰할 수 있는 동반자 Bootstrap에 의지하고 그것에 대해 약간의 가벼운 스타일링을 할 것입니다.
첫 번째 플레이어가 "시작" 버튼을 클릭하면 게임 그리드가 플레이어의 피어 ID와 함께 표시됩니다. 그런 다음 플레이어는 이 피어 ID를 상대방과 공유할 수 있습니다.
두 번째 플레이어는 클릭한 다음 "가입" 버튼을 클릭하고 첫 번째 플레이어의 피어 ID를 입력하고 게임을 시작할 수 있습니다.
그것을 밖으로 시도
https://arteegee.herokuapp.com에서 이 예제 애플리케이션을 사용해 볼 수 있습니다.
또는 GitHub에서 리포지토리를 복제하고 NPM 종속성을 설치하고 로컬에서 사용해 볼 수 있습니다.
git clone https://github.com/hjr265/arteegee.git cd arteegee npm install PORT=5000 npm start
서버가 실행되면 웹 브라우저를 http://localhost:5000으로 지정하고 한 탭에서 게임을 시작하고 피어 ID를 사용하여 다른 탭(또는 다른 WebRTC 지원 웹 브라우저)에서 참여할 수 있습니다.
웹 브라우저의 콘솔을 열어 일부 디버그 정보를 볼 수 있습니다. 이 예제 애플리케이션에서 PeerJS 클라이언트는 자세한 로깅을 수행하도록 구성되어 있습니다.
하지만 그것은 나를 위해 작동하지 않습니다!
이 게임이 컴퓨터에서 작동하지 않을 수 있는 두 가지 주요 이유가 있습니다.
필요한 WebRTC API를 아직 지원하지 않는 웹 브라우저를 사용 중일 수 있습니다. 이 경우 WebRTC 및 데이터 채널을 지원하는 다른 브라우저를 사용해 볼 수 있습니다.
WebRTC를 지원하는 최신 웹 브라우저를 사용하는 경우 WebRTC가 침투할 수 없는 일부 네트워크 인프라 뒤에 있을 가능성이 있습니다. 이상적으로는 이 문제를 TURN 서버로 쉽게 해결할 수 있지만 예제 응용 프로그램은 TURN 서버를 사용하지 않기 때문에 나와 상대방이 NAT 뒤에 있을 때는 작동하지 않습니다.
결론
WebRTC는 새로운 기술이며 그 구현은 아직 성숙하지 않았습니다. 이는 종종 개발자에게 몇 가지 고유한 문제를 야기합니다. 그러나 거친 원시 API를 깔끔하게 추상화하는 PeerJS와 같은 라이브러리를 사용할 수 있게 되면서 기술에 이미 액세스할 수 있게 되었습니다.
PeerJS 기반 게임 구축을 위한 이 간단한 튜토리얼이 WebRTC를 시작하고 놀라운 실시간 P2P 웹 애플리케이션을 구축하는 데 도움이 되기를 바랍니다.