ASIO後押し:接続されたクライアントのリストを維持
-
12-09-2019 - |
質問
私はブーストASIO <のhref =「http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/examples.html」のrel =」を修正するための最良の方法を探していますnoreferrer nofollowを "> HTTPサーバ3の例では、現在接続しているクライアントのリストを維持するためにを。
私はとしての例からserver.hppを変更する場合:
class server : private boost::noncopyable
{
public:
typedef std::vector< connection_ptr > ConnectionList;
// ...
ConnectionList::const_iterator GetClientList() const
{
return connection_list_.begin();
};
void handle_accept(const boost::system::error_code& e)
{
if (!e)
{
connection_list_.push_back( new_connection_ );
new_connection_->start();
// ...
}
}
private:
ConnectionList connection_list_;
};
そして、私台無しそれはスコープの外に出ると、それはまだConnectionListで維持参照を持っているため、クライアントからの接続を切断しないように接続オブジェクトの寿命を。
代わりに、私のConnectionListがtypedef std::vector< boost::weak_ptr< connection > > ConnectionList;
のように定義されている場合は、私は、誰かがGetClientList()
からそれを使用している間にそのポインタを切断し、無効化クライアントのリスクを実行します。
誰もがこれを行うには良い&安全な方法での提案がありますか?
おかげで、 PaulH
解決
HTTPはステートレスです。それは、それも、クライアントがを任意の時点で全角>であるのを追跡することはもちろんのこと、どのような「現在接続しているクライアント」の手段を定義することは困難であることを意味します。 があります唯一の時間は本当にの「現在のクライアントは、」要求は、その要求がサービスされた時間(多くの場合、わずか数ミリ秒)に受信された時点からです。接続が一つでもページのダウンロードの期間中維持されていない - 。なく、ページ上の各項目は、要求され、別々に送信された
彼らは要求に送った後、クライアントは時間のいくつかの任意の長さのために、「接続」と考えられている(数分) -これを処理するための典型的な方法はかなり単純なタイムアウトを使用することです。ある種のクッキーが特定のリクエストに送信するクライアントを識別するために使用されます。
あなたが何を言ってるのかの残りの部分では、接続情報を保持するために使用したコレクションがスレッドセーフであることを確認することだけの問題です。あなたは1人の接続を追加したスレッド、それらを削除し、1つのスレッドおよびリスト内の現在のデータを使用してN個のスレッドを持っています。標準のコレクションは、任意のスレッドの安全性を保証するものではありませんが、それを行うの周りの他の人が存在します。
他のヒント
申し訳ありませんが、私がコメントするのに十分な評判を持っていないので、私はそれをここに書きます。
答えのコメント: の「HTTPはステートレスである」 - が、接続はステートフルです! 、あなたはHTTPサーバを実装するので、もしあなたが同じ接続で別の要求を待つ必要があります慎重にHTTP / 1.1のドキュメントを読んでください、デフォルトの動作は「キープアライブ接続」です。これは、HTTPSのために特に重要であるハンドシェイクの数を減らすことで多くの時間を節約できます。すべての準拠したサーバが接続を維持する方法を理解しなければならない理由です。の
質問については、いくつかのロジックはあなたの中にあり、「接続」クラス - 非同期操作のすべてのハンドラでは、あなたが別の非同期操作を開始したり、全体の連鎖停止のいずれか
(エラー、すべてが行われ、など。)tell_server_im_doneのように、その関数のリストから自分を削除するためにあなたの「サーバー」インスタンスを教えて、あなたの「接続」クラス内の関数を記述します。あなたは、この作業では、「接続」コンストラクタをあなたのサーバーオブジェクトへのポインタまたは参照を、あなたを与える必要があります。
マルチスレッドのアドバイス:シングルスレッドですべてを行うことによって開始します。あなたは、いくつかのスレッドで右全体のことを行うためにスレッドをよく理解する必要があるので、あなたのサーバーが過負荷にされていない場合は、シングルスレッド、できるだけ長くそれを維持します。 :)