PeerJSでWebRTCを使いこなす:シンプルなP2PWebゲームの作成

公開: 2022-03-11

WebRTCは、Webブラウザー間のリアルタイム通信を可能にするテクノロジーです。 これは比較的新しいものであり、API定義はまだドラフトと見なされています。 WebRTCがまだすべての主要なWebブラウザーでサポートされていないという事実と相まって(そして、サポートしているものの中には、このテクノロジーのすべての機能をサポートしていないものもあります)、これにより、ミッションクリティカルなアプリケーションにWebRTCを使用することが比較的困難になります。 またはそう思うでしょう!

PeerJSを使用してWebRTC経由でFourを接続します。サーバーはありません。

PeerJSを使用してWebRTC経由でFourを接続します。サーバーはありません。
つぶやき

2011年5月にGoogleによって最初に導入されて以来、WebRTCは多くの最新のWebアプリケーションで使用されてきました。 多くの最新のWebブラウザーのコア機能であるため、Webアプリケーションはこのテクノロジーをシームレスに利用して、さまざまな方法でユーザーエクスペリエンスを向上させることができます。 肥大化したブラウザプラグインを必要とせず、ピアツーピア(P2P)ネットワークを利用できる(一部のサーバーを介してすべてのデータを送信するわけではない)ビデオストリーミングまたは会議アプリケーションは、 WebRTCで実現できます。

この記事では、WebRTCを使用してConnectFourのシンプルなP2PWebゲームを作成する方法を見ていきます。 WebRTCのさまざまなラフエッジと実装の違いを回避するために、すばらしいJavaScriptライブラリであるPeerJSを使用します。

WebRTCを介したデータ

始める前に、WebRTCはオーディオおよびビデオストリームの送信だけではないことを理解することが重要です。 また、P2Pデータチャネルのサポートも提供します。 これらのチャネルには、信頼できるものと信頼できないものの2つのバリエーションがあります。 ご想像のとおり、信頼できるデータチャネルはメッセージが配信され、順番に配信されることを保証しますが、信頼性の低いチャネルはそのような保証を提供しません。

WebRTCインフラストラクチャ-頭字語の海

WebRTCインフラストラクチャ-頭字語の海
つぶやき

さらに、WebRTCデータチャネルは、一般的なWebRTCピア接続に必要なもの(ピア間の接続を調整するためのシグナリングサーバー、ピアのパブリックIDを把握するためのSTUNサーバー、およびオプションでTURNサーバー)以外に、特別なインフラストラクチャのセットアップを必要としません。ピア間の直接接続を確立できない場合(たとえば、両方のピアがNATの背後にある場合)にピア間でメッセージをルーティングします。 これらの頭字語がおなじみのように聞こえる場合、それはWebRTCが可能な限り既存のテクノロジーを再利用しているためです。

これにより、マルチプレイヤーゲーム、コンテンツ配信、ファイル共有など、WebRTCのより多くのユースケースへの扉が開かれます。 繰り返しになりますが、すべて仲介サーバーを必要とせず、したがって待ち時間が短くなります。

単純なWebゲームでは、2つのWebブラウザー間のデータチャネルを使用して、プレーヤーの動きを前後に伝達します。

PeerJSに会う

PeerJSは、ブラウザーにWebRTCを実装し、シンプルで一貫性のあるエレガントなAPIをラップします。 これは、以前のブラウザーのWebRTC実装のさまざまな穴を塞ぎます。 たとえば、Chrome 30以前では、信頼性の低いデータチャネルしか利用できませんでした。 PeerJSは、信頼できるデータチャネルを使用するように構成されている場合、これらの古いブラウザーにはシムを使用します。 これは、信頼できるチャネルのネイティブ実装ほどパフォーマンスは高くありませんが、それでも機能します。

PeerJSを使用すると、ピアの識別がさらに簡単になります。 すべてのピアは、IDのみを使用して識別されます。 ピアが自分自身を選択できる文字列、またはサーバーに生成させる文字列。 WebRTCはピアツーピア通信を約束しますが、接続ブローカーとして機能し、シグナリングを処理するには、とにかくサーバーが必要です。 PeerJSは、クラウドでホストされているバージョン(現在は無料で、いくつかの制限があります)を使用したくない場合に備えて、この接続ブローカーサーバーPeerJSサーバー(Node.jsで記述)のオープンソース実装を提供します。

FourGoesP2Pを接続する

WebRTC、つまりPeerJSを操作するための自信の源ができたので、簡単なNode.js/Expressアプリケーションを作成することから始めましょう。

 npm init npm install express --save npm install jade --save npm install peer --save

これは、PeerJSサーバーをホストし、ページとフロントエンドアセットを提供するためにのみ使用します。 1ページだけを提供する必要があり、これには2つのセクションが含まれます。プレーンなメインメニューと、7x6のConnectFourグリッドです。

PeerJSサーバー

独自のPeerJSサーバーをホストするのは本当に簡単です。 GitHubの公式リポジトリには、ワンクリックボタンでPeerJSサーバーのインスタンスを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オブジェクトをインスタンス化するときにすべてのピアに対して1つ選択することができます。

 var peer = new Peer(id, options)

ここで、サーバーにidを生成させたい場合は、 idを完全に省略できます。 私たちの場合、それが私たちがやりたいことです。 PeerServerは、提供するIDが一意であることを確認します。 2番目の引数optionsは通常、キーを含むオブジェクトです(クラウドでホストされているPeerServerを使用している場合はAPIキー、PeerServerを自分でホストしている場合はホストポートパスなど)。

 var peer = new Peer({ host: location.hostname, port: location.port || (location.protocol === 'https:' ? 443 : 80), path: '/peerjs' })

2つのPeerJSピア間の接続を確立するには、一方のピアがもう一方のピアのIDを知っている必要があります。 物事を簡単にするために、Connect Four over WebRTCの実装では、ゲームを開始するプレーヤーに、対戦相手とピア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形式でエンコードした後、ピア間でデータを送信します。 これにより、ピアは文字列、数値、配列、オブジェクト、さらにはブロブを通信できます。

着信データを受信するには、 connで「data」イベントをリッスンするだけです。

 conn.on('data', function(data) { // data === 'hello' })

そして、それは私たちが必要とするほとんどすべてです!

ゲームロジック

ゲームを開始した最初のプレーヤーには、PeerJSによって生成されたピアIDが表示され、対戦相手と共有できます。 対戦相手が最初のプレイヤーのピアIDを使用してゲームに参加すると、最初のプレイヤーは移動することができます。

シンプルなルールとメカニズムのゲームであるConnectFourには、1種類の動きしかありません。各プレーヤーは、順番に、列を選択してディスクをその中にドロップする必要があります。 これは、ピアが通信する必要があるのは、現在のプレーヤーがディスクをドロップインすることを選択した列番号だけであることを意味します。この情報は、文字列「move」と番号-0-の2つの要素を持つ配列として送信されます。左からの列のベースのインデックス。

プレーヤーが列をクリックするたびに:

 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の完全なソースコードはここにあります。

すべてを接続する

すべてを組み合わせるために、2つのセクションを持つ単純なページを作成します。 ページの読み込み時に、メインメニューを含むセクションが表示され、ゲームグリッドを含むセクションは非表示のままになります。

 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 | &nbsp; 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を対戦相手と共有できます。

新しいゲームを開始し、PeerJSによって生成されたピアIDを共有します

2番目のプレーヤーは、[参加]ボタンをクリックしてからクリックし、最初のプレーヤーのピアIDを入力して、ゲームを開始できます。

対戦相手のピアIDを使用してゲームに参加する

試してみる

このサンプルアプリケーションは、https://arteegee.herokuapp.comで試すことができます。

または、GitHubからリポジトリのクローンを作成し、NPMの依存関係をインストールして、ローカルで試すことができます。

 git clone https://github.com/hjr265/arteegee.git cd arteegee npm install PORT=5000 npm start

サーバーが実行されたら、Webブラウザーでhttp:// localhost:5000を指定し、あるタブからゲームを開始し、ピアIDを使用して別のタブ(または別のWebRTC対応Webブラウザー)から参加できます。

このサンプルアプリケーションでは、PeerJSクライアントが詳細ログを実行するように構成されているため、Webブラウザのコンソールを開いてデバッグ情報を確認できます。

しかし、それは私にはうまくいきません!

このゲームがコンピュータで動作しない主な理由は2つあります。

必要なWebRTCAPIをまだサポートしていないWebブラウザを使用している可能性があります。 その場合は、別のブラウザー(WebRTCとデータチャネルをサポートするブラウザー)を試してみることをお勧めします。

WebRTCをサポートする最新のWebブラウザーを使用している場合は、WebRTCが侵入できないネットワークインフラストラクチャの背後にいる可能性があります。 理想的には、この問題はTURNサーバーで簡単に対処できますが、サンプルアプリケーションはこれを使用していないため、あなたと対戦相手の両方がNATの背後にいる場合は機能しません。

結論

WebRTCは新しいテクノロジーであり、その実装はまだ成熟していません。 これらは多くの場合、開発者にいくつかの固有の課題を引き起こします。 ただし、大まかな生のAPIをきちんと抽象化するPeerJSのようなライブラリが利用できるようになったことで、このテクノロジーはすでにかなりアクセスしやすくなっています。

PeerJSベースのゲームを構築するためのこの簡単なチュートリアルが、WebRTCの使用を開始し、驚くべきリアルタイムのピアツーピアWebアプリケーションを構築するのに役立つことを願っています。