5

サーバー全体に1つのPHPクラスのインスタンス化されたオブジェクトがいくつあるかを知ることは可能ですか(1つのスレッドだけでなく、すべてのユーザーに対して)。

やりたい理由はここにあります。私はカードゲームを作成していますが、ルームクラス(一意のルーム名、ルームで現在オンラインのプレーヤー、ソックスIDなど)を持ちたいので、ユーザーがサーバーに参加してアクティブなルームの新しいリストを取得します。そして、1 つの部屋がキャンセル (破棄) されると、その情報 (基本的にリアルタイムの部屋のステータス) をすべてのユーザーに送信します。


わかりました、これが私がそれをしたい理由です。私はカードゲームプロジェクトを作成しており、ルームクラス(一意のルーム名、ルームで現在オンラインのプレイヤー、ソックスIDなど)を持ちたいので、ユーザーがサーバーに参加してアクティブなルームの新しいリストを取得します。そして、1つの部屋がキャンセル(破棄)されると、その情報(基本的にリアルタイムの部屋のステータス)をすべてのユーザーに送信します。私がやりたいことを理解していただければ幸いです。

4

3 に答える 3

4

マルチユーザーゲームを実装したいので、クライアントサーバーアーキテクチャを使用する必要があります。マシン上で実行され、ゲームの状態を追跡する単一の永続的なサーバープロセスを設定します。各ユーザーリクエストは、ゲームサーバーと通信して必要なすべての情報を要求するPHP「クライアント」スクリプトによって処理されます。

このようにして、すべてのRoomオブジェクトとすべてのプレーヤーの状態が1つのプロセス(サーバー)に存在します。Webサーバー(ゲームサーバーと混同しないでください)はクライアントスレッドを起動し、任意の方法でゲームサーバーと非同期で通信します。

状況が非常に単純な場合は、サーバープロセスを、ゲームの現在の状態のスナップショット(アクティブな部屋と関連するプレーヤーの完全なリストを含む)を格納する一元化されたデータベースに置き換えることができる場合があります。各ユーザーリクエストは、データベースからゲームの状態をロードし、変更を書き出します。しかし、実行時間の長いサーバーの方が簡単な方法だと思います。

編集:あなたの質問は、PHPがどのように機能するかについての混乱を示唆しています。サーバーがユーザー要求を処理するために起動するPHPスレッドは、非常に短命です。1時間そこにいた5人のプレーヤーがいるとしましょう。数分または数秒ごとに、プレーヤーがWebサーバーにリクエストを送信します。サーバーは、リクエストを処理して終了するPHPスレッドを起動します。ゲームは数時間続く可能性がありますが、ほとんどの場合、実行中のスレッドはなく、カウントするクラスのインスタンスもありません。常に、アクティブな接続がないプレーヤーがいることになります。したがって、リクエスト間でゲームの状態を保持するために、ある種の永続的なエンティティが必要です。また、それを一意にすることもできます

編集2:少し頭がおかしいようですので、2番目のオプションを選択する必要があります。プロセス間通信を忘れて、データベースにゲームの状態を保持します。

各phpリクエストは1人のプレイヤーのアクションです。ユーザーがボタンなどをクリックすると、phpスクリプトがデータベースから、ゲームの現在の状態をモデル化するために必要なすべての情報をロードします。必要なハウスクリーニングを実行し(ずっと前に再生を停止したユーザーを非アクティブ化し)、ユーザーのアクションを処理し、データベースへの変更を保存して、ユーザーの新しいページを生成します。その後、終了します。それはすべてほんの一瞬です。次に、次のユーザー(または同じユーザー)が別のアクションを送信し、最初からやり直します。

並行性についてはどうですか?多くのユーザーを獲得でき、スクリプトが非常に遅い場合を除いて、スクリプトはありません。一度に実行するスクリプトのコピーは1つだけです。同時実行を禁止する場合は、データベーストランザクションを使用して、ユーザーアクションが一度に1つずつ処理されるようにします。それでも不十分な場合は、クライアントサーバーアーキテクチャ、プロセス間通信、およびクライアントサーバーソリューションに必要なその他すべてのことについて学びます。

于 2013-03-01T20:42:34.507 に答える
2

これは間違いなく大まかなアプローチですが、クラスのコンストラクターに何かを入れるだけです。その何かは、何かをログに記録したり、何かを電子メールで送信したり、カウンターを読んだり、インクリメントしたりすることができます...

明らかに、特定の時点でのインスタンスの数を知りたい場合は、デストラクタにも何かが必要になります...

回答を読んだ後 (元の質問に対するコメントである必要があります)、これを実装する最善の方法は、クラス メソッドとプロパティを使用することです。これにより、任意のインスタンスが共有カウントを読み取り/変更できるようになります。コンストラクタとデストラクタを使用して、アクティブなテーブルの数を増減することはできますが、クラスは単一の数を維持し、すべてのインスタンスからアクセスできます。

于 2013-03-01T20:20:37.873 に答える
0

短い答えはノーです。非常に長く複雑な答えは「はい」ですが、大量のハッキングが必要であり、php ソースを編集するか、gdb (またはそのようなもの) を使用して実行中のメモリを検査する必要があります。私の知る限り、これに対するすぐに使えるサポートはまったくありません。

より良い質問は、なぜこれが必要なのですか? おそらく、別の方法で解決する方がはるかに簡単な問題を解決しようとしています。

オブジェクトのインスタンス化と破棄で APC のインクリメントとデクリメントを使用するだけで回避できるかもしれませんが、これらのオブジェクトが実際に非常に多く、それらをカウントする必要がある場合は、大きなパフォーマンスの問題を引き起こす可能性があります。

于 2013-03-01T20:20:20.300 に答える