2010-11-23 19 views
10

私はウェブブラウザベースのマルチプレイヤーゲームを作っています。私は、リアルタイム性を考慮してWebSocketが通信を処理する最良の方法であると判断しました。クライアントはHTML5キャンバスを使用してゲームとWebソケットをホストと通信します。PHPゲームサーバー、複数のTCPクライアント?

私は、ホスティングプロバイダによって好まれるように、ゲームをホスティングするためにPHPを使用することに決めました。私は以前はPHPを使用していませんが、JavaのWebソケットと同様のことをしましたが、マルチスレッドに大きく依存しています。

私は、複数のクライアントを持つPHPソケットに関するチュートリアルをいくつか見てきました。それらのほとんどは、各クライアントの新しいプロセスをフォークするようなことを行います。私は絶えず走っているゲームループがあるので、これは適切ではないと私は思う。

私が達成しようとしているのは、接続時に新しいクライアントをリッスンし、クライアントの現在のリストとデータを交換し、ゲームループを一括して実行するときに、各クライアントにポートを割り当てる方法です。私は助けを必要と

場所は以下のとおりです。

  • 見つけ、新しいクライアントにポートを割り当て、そのポートのクライアントに通知し、彼らは外したときに、それをクリーンアップする方法。
  • ゲームのループをブロックすることなく、上記と他のすべてのソケットトランザクションを実行する方法。部分的なチャンクでクライアントからのメッセージを受け入れ、完全なメッセージにのみ応答することは容認できる。

これらの目標を達成するための技術的アドバイスはありますか? 私はこれがすべてPHPの質問に多すぎるとは思わないが、私が間違っている場合は私を修正する!

私が理想的にはサーバー側を達成したいと思っている疑似コード。どの機能もブロックする必要はありません。 アレイクライアント。

while(gamerunning) 
{ 
    CheckForNewClients(); 
    GetStatusFromClients(); 
    DoGameUpdate(); 
    SendGameStateToClients(); 
} 

[更新] 興味がある人々のために、私は、より多くの意味を作るように見えたとしてではなく、実際のWebサービスよりも(特にJava、および「TooTallNatesのWebソケットライブラリを使用して)ウェブソケットをサポートする専用のアプリケーションを作成しました偶然にも、ほとんどのWebブラウザはセキュリティ問題のためにビン内のWebソケットを盗んだようです。

+1

Node.jsを実行できるVPSなどを入手できる場合は、ノードパスを使用することを強くお勧めします。 Node.jsのマルチプレイサーバーはケーキです。 –

+0

node.jsはWebサイトのクライアント側のソリューションではありませんか? –

+0

いいえ、nodejsは短くて高速で、イベントドリブンで、サーバーを書くためのサーバーサイドのjavascriptです。 –

答えて

5

このタイプのアプリケーションにPHPを使用することはお勧めしません。 PHPは公式にマルチスレッドをサポートしておらず、未定義の期間(サーバのような)でPHPスクリプトを実行するのは実際には広告された機能ではありません。あなたは本当に(これを効果的に行うために、PHPのデーモンを実行する必要がありますあなたがしようと歴史:)

作ることができます。もちろん、

(私は間違えてるなら、私を修正してください)

+2

多分私は歴史を作っています...私は過去にPHPでソケットサーバーデーモンを行っています(私の雇用主が強制しているのでその技術)、私は問題が何かを見ていない。単一のプロセスでも複数のプロセスでもうまく動作します。 – netcoder

+1

同じですが、私は現在PHPでゲームバックエンドを作成しています(デーモンとして)。 XMPPゲートウェイ経由でメッセージをリッスン/ライトします。これまでのところ、非常にうまく動作します(超高速ではありませんが、PHPの使い勝手を上回ることはできません)。 –

+1

@ケンドール:私はスピードが本当に問題だとは思わない。私はJavaでソケットデーモンも書いてきました。そして、PHPはスピードに敏感です。まず、開始するJVMはありません。第二に、PHPはJavaの抽象ソケット層とは異なり、Cのrawソケットに非常に近いです。 – netcoder

7

とそれはPHP 5.3である必要があります)。私はPHP for daemon processesを使用することのかなり完全な概要を書いた。あなたが選んだものは、イベントベースのループシステムを使うことをお勧めします。

私はLooPHPと呼ばれる基本的なRunLoopライブラリを設計しました。これはおそらく、特に*_selectを扱う場合に役立ちます。私はそれについてあなたが持っている疑問に答えることができて嬉しいです。

EDIT:単純なコマンドのリストをwhileあなたは、あなたがリスナーに反応しないイベントベースのシステムでは

。たとえば...

代わりの

はやって:

while(1) { 
    ... /* listen, react */ 
} /* repeat */ 

ランは、上記の場合は1非常に簡単です

class ReactClass { ... } 

$loop = new LooPHP_EventLoop(new ReactClass); 

//add one time event 
$loop->addEvent(function() { 
    print "This event was called 0.5 second after being added\n"; 
}, 0.5 /* in seconds */); 

//this creates a repeating event, this is called right away and repeats 
$add_event = function() use ($loop, &$add_event) { 
    print "This event is REPEATEDLY called 0.1 every second\n"; 
    $loop->addEvent($add_event, 0.1); 
}; 
$add_event(); 

//start the loop processing, no events are processed until this is done 
$loop->run(); //php doesn't leave this call until the daemon is done 
exit(0); //cleanly exit 

リスナー(ソケット、および他の非同期イベントジェネレータ)を登録することで、作業をループソースEventLoopと手動でタイムド機能を追加することができます(これらはReactClassの呼び出し内からでも追加できます)。

私は、非同期のイベントフィードをバックエンドに(ソケット経由で)提供する必要があり、元のイベントから関数を任意にオフセットして呼び出す機能が必要でした(タイムアウトしたクライアント、等)。

さらに詳しい例をご希望の場合は、githubに記載されています。

この情報が役に立ちましたら幸いです。

+0

any1ガーナの働きについて知っていますか?私はあまりにも助けが必要です... – booota

+0

私はこれの外観が好きです。これを設定する方法を教えて、イベント関数が別々のゲームループで絶えず更新されているオブジェクトの配列にアクセスできるようにしてください。 –

+0

@Toby Wilson私は自分の投稿を更新しました。それが役に立ったら教えてください。 –

関連する問題