0

回答について: Boost:Asio を使用したゲームサーバーは非同期で動作しますか?

計算を行い、同時にクライアントからパケットを送受信するサーバーがある場合はどうなりますか?

私がhttpサーバーをコーディングしていた場合、送信されたすべてのデータは受信されたデータの関数であるため、回答の例で十分です。

私のプログラムが値を計算し、必要に応じてクライアントを更新する必要があると仮定します (更新頻度を 1 Hz にしたい場合、別の頻度を 10 Hz にしたい場合など)。

この種の構造は私にとって非常に役立ちます:

while(1){
pollNetworking(); //<- my function
value1 += 5; value2 = random();
}

私の pollNetworking 関数では、acceptor.accept(*socket,10); のようなものを呼び出すことを考えていました。ここで、10 はミリ秒単位のタイムアウトですが、タイムアウト パラメータがないため、これを構成する方法がわかりません。

スケーラビリティは最大の問題ではありません。ソケットごとに 1 つのスレッド、受け入れ用の追加のスレッド、および計算用の別のスレッドを生成できますか? これは簡単に実装できますか? 私はこれを可能な限り安定させたいので、次に速度、次にスケーラビリティです。マルチスレッドに関しては、まだきれいにコーディングしてデバッグできるとは思っていません。

編集: io_service::poll を使用できることを学びました。これは、ブロックせずに準備完了イベントのみをディスパッチします。したがって、必要に応じて、タイムアウトが0の同期関数です。

4

2 に答える 2

1

サーバーは、クライアントとの間でデータを送受信すると同時に計算を実行できます。ただし、バッファとソケットは同時実行アクセスから保護する必要がある可能性があります。

ほとんどのBoost.Asio操作では、ポータブルタイムアウト機能は非同期アクションでのみ可能です。これには、エンティティに対して非同期操作を発行し、タイマーを設定してから待機する必要があります。async_readタイムアウトによるキャンセルの例については、この質問を参照してください。

最も単純でスケーラブルではないアプローチは、責任ごとにスレッドを指定することです(ソケットごとのスレッド、受け入れ、および計算)。計算結果の保護など、同期が必要になる可能性があります。たとえば、value1value2が同じ反復でのみ意味がある場合、ソケットスレッドは、計算スレッドが書き込み中に値を変更することなく、値が一緒に書き込まれることを保証する必要があります。Boost.Threadによって提供されるものなど、さまざまな同期構造を使用して、これを実現できます。また、使用される非同期呼び出しの量を最小限に抑えることで、実装とデバッグが容易になる場合があります。

非常にスケーラブルなアプローチの場合、プログラムのほとんどは、非同期操作から呼び出される一連のハンドラーとして記述されます。これにより、プログラムはスレッドとスレッドプールをはるかに簡単に利用できるようになります。ただし、プログラムロジックが多数の機能に分散する可能性があり、すぐに追跡が困難になる可能性があります。多くの場合、非同期アクションを念頭に置いて作成されたプログラムは、との同期を実行しboost::asio::strand、を介してオブジェクトの存続期間を管理しますboost::shared_ptr

実装の容易さは経験に依存します。ネットワークプログラミング、同時実行性、および非同期操作は本質的に難しいことに注意してください。シンプルで完全なソリューションはめったにありません。

于 2012-08-15T13:37:12.693 に答える
0

非同期の受け入れと受信を引き続き行うことができますが、クライアントに送信する必要があるときはいつでもクライアントに同期して送信できます。

接続されたクライアントごとに個別のスレッドを使用できる場合 (数百または数千の接続は想定されていないと思います)、受信を非同期に保ちながら、接続されたクライアントごとに 1 つのスレッドを計算と送信の両方に使用できます。

于 2012-08-14T13:03:28.033 に答える