Muduoネットワークプログラミングの例7:「シリアル変換」接続サーバとその自動化テスト
10203 ワード
Muduoネットワークプログラミング例の7:接続サーバとその自動化テスト
陳碩(giantchen_AT_gmail)
Blog.csdn.net/Solstice t.sina.com.cn/giantchen
『Muduoネットワークプログラミングの例』シリーズの7番目の記事です.
Muduo全シリーズ記事リスト:http://blog.csdn.net/Solstice/category/779646.aspx
この文書では、test harnessを使用して内部論理を持つネットワークサービスプログラムをテストする方法について説明します.
本明細書のコードはhttp://code.google.com/p/muduo/source/browse/trunk/examples/multiplexerを参照
ダウンロードアドレス:http://muduo.googlecode.com/files/muduo-0.2.0-alpha.tar.gz SHA 1 checksum:75 a 09 a 82 f 96 b 583004876 e 95105 c 679 e 64 c 95715
雲の風は彼のブログでネットゲーム接続サーバの機能要件(「練習プロジェクト」を検索)に言及し、私はC++でこれらの需要を初歩的に実現し、muduoネットワークライブラリの例としてセットの自動化test harnessを作成しました.
注意:本明細書で示すコードは、基本的な機能要件のみを実現し、セキュリティを考慮せず、特にパフォーマンスを最適化するものではなく、実際にパブリックネットワーク上で実行されるネットワーク・ゲーム接続サーバとして使用するのに適していません.
機能要件
この接続サーバは、複数のクライアント接続を1つの内部TCP接続に集約し、「データ列並列変換」の役割を果たし、backendの論理サーバがマルチ接続の同時性を考慮することなく業務に専念できるようにする.以下はシステムのブロック図です.
この接続サーバの役割はデジタル回路のデータセレクタ(multiplexer)と似ているので、multiplexerと名付けました.△実はIO-Multiplexingもこの意味で、1つのthread-of-controlが複数のIOファイル記述子を選択的に処理できるようにしています.
(上図はwikipediaから取ってpublic domain著作権です)
インプリメンテーション
Multiplexerの機能要件は複雑ではなく、backend connectionとclient connectionsの間でデータを逆騰させることにほかならない.具体的には、主に4つのイベントを処理します.新しいclient connectionごとに新しい整数idを割り当てます.idが切れたら、すると、新しい接続が切断される(これによりidの数を制御することで最大接続数を制御できる).また、idが早すぎる多重化を避けるためにmultiplexerはqueueを用いてfree idを管理し、キューのヘッダからidを取るたびに、使い終わった後にqueueの末尾に戻す. クライアント接続が到着または切断されたときにbackendに通知する.onClientConnection() http://code.google.com/p/muduo/source/browse/tags/0.2.0/examples/multiplexer/multiplexer_simple.cc#54 client connectionからデータを受信した場合、connection idとともにbackendにデータを送信する.onClientMessage() http://code.google.com/p/muduo/source/browse/tags/0.2.0/examples/multiplexer/multiplexer_simple.cc#117 backend connectionからデータを受信すると、どのclient connectionにデータが送信されたかを判別し、対応する転送操作を実行する.onBackendMessage() http://code.google.com/p/muduo/source/browse/tags/0.2.0/examples/multiplexer/multiplexer_simple.cc#194 backend connectionが切断された場合、すべてのclient connectionsが切断されます(clientが自動的に再試行されると仮定します).onBackendConnection()http://code.google.com/p/muduo/source/browse/tags/0.2.0/examples/multiplexer/multiplexer_simple.cc#162 上から見るとmultiplexerの機能はproxyとよく似ている.multiplexer_simple.ccは、muduoのio-multiplexing特性により、複数の同時接続を容易に処理できる単一スレッド版の実装である.
実装には、次の2つの点に注意してください. TcpConnectionのidはどのように保存しますか?backendからデータを受信した場合、idに基づいて対応するclient connectionを見つけるにはどうすればいいですか?クライアント接続からデータを受信した場合、idをどのように知るか?
最初の問題はstd::map〈int,TcpConnectionPtr〉clientConns_;idからclient connectionへのマッピングを保存すればいいです.
2つ目の問題は似たような方法で解決できますが、muduo::net::TcpConnectionのcontext機能を紹介したいと思います.各TcpConnectionにはboost::anyメンバーがあり、顧客コードによって自由に支配されます(get/set).コードは以下の通りです.このboost::anyはTcpConnectionのcontextで、接続にバインドされた任意のデータ(例えば、接続ID、接続の最終データ到着時間、接続に代表されるユーザの名前など)を保存するために使用できます.これにより、クライアントコードはTcpConnectionを継承する必要がなく、attach自身の状態をattachすることができ、TcpConnectionFactoryも使用できません.(継承が許可されている場合は、必ずTcpServerにこのfactoryを注入します).
Multiplexerの場合、onClientConnection()でconn->setContext(id)を呼び出し、TcpConnectionオブジェクトにidを格納します.onClientMessage()はTcpConnectionオブジェクトからidを取得し、データとともにbackendに送信し、以下のように完全に実現される. TcpConnectionのライフサイクルはどのように管理されますか?Client Connectionは動的に作成され、破棄されるため、その生滅は完全に顧客によって決定され、backendがデータを送信したいときに、このTcpConnectionオブジェクトがまだ生きていることをどのように保証しますか?解決策はreference counting、もちろん、自分で書く必要はなくboost::shared_ptrでいいです.TcpConnectionはmuduoで唯一デフォルトでshared_を採用していますptrはライフサイクルのオブジェクトを管理し,その動的ライフサイクルの本質によって決定される.詳細については、陳碩『解析関数がマルチスレッドであるC++のスレッドで安全なオブジェクトコールバックに遭遇した場合』 を参照してください.
Multiplexerはバイナリプロトコルですが、どのようにテストしますか?
テストの自動化
Multiplexerはmuduoネットワークプログラミングの例の中で初めてnon-trivialビジネスロジックを持つネットワークプログラムで、陳碩の「分散プログラムの自動回帰テスト」の一文の思想に基づいて、私はそれのためにtest harnessを編纂しました.コードはhttp://code.google.com/p/muduo/source/browse/trunk/examples/multiplexer/harness/src/com/chenshuo/muduo/example/multiplexerを参照
このTest harnessはJavaで作成され、Nettyライブラリを使用しています.このtest harnessはclientsとbackendを演じ、つまり積極的に接続を開始するだけでなく、受動的に接続を受け入れなければならない.またtest harnessとmultiplexerの起動順序は任意ですので、どうすればいいかコードを読んでください.構造は次のとおりです.
Test harnessは様々なeventをblocking queueに集め、test caseの作成を容易にします.Test caseはtest harnessを操作し、接続を開始し、データを送信し、受信したデータをチェックします.例えば、以下はいずれかのtest caseです.
http://code.google.com/p/muduo/source/browse/trunk/examples/multiplexer/harness/src/com/chenshuo/muduo/example/multiplexer/testcase/TestOneClientSend.java
ここでいくつかのtest casesはjavaで直接書かれていますが、必要であればGroovyで書くこともできます.これにより、test harnessを再起動せずにいつでもtest casesの追加を変更することができます.具体的なやり方は陳碩の『「ファミリー」版のモバイルオフライン課金システムの実現』を参照してください.
将来の改善は、この自動化されたtest harnessがあり、multiplexerを比較的便利かつ安全に修正(さらには再設計)することができます.例えば、「backend送信命令切断クライアント接続」の機能を追加します.自動化テストがあれば、この新しい機能は、本物のbackendが参加する必要がなく、単独でテストすることができます. Multiplexerをマルチスレッド書き換えに変更します.自動回帰テストがあれば、既存の機能を破壊する心配はなく、安心して大胆に書き換えることができます.またtest harnessは外部からのテストであり、ユニットテストではないため、multiplexerを書き換えるときにtest casesを動かさず、テストの安定性を保証します.さらに、このtest harnessは、マルチスレッドmultiplexerの正確性を検証するためにも、単一スレッド版に比べて効率を向上させるためにもstress testingを行うことができます.
陳碩(giantchen_AT_gmail)
Blog.csdn.net/Solstice t.sina.com.cn/giantchen
『Muduoネットワークプログラミングの例』シリーズの7番目の記事です.
Muduo全シリーズ記事リスト:http://blog.csdn.net/Solstice/category/779646.aspx
この文書では、test harnessを使用して内部論理を持つネットワークサービスプログラムをテストする方法について説明します.
本明細書のコードはhttp://code.google.com/p/muduo/source/browse/trunk/examples/multiplexerを参照
ダウンロードアドレス:http://muduo.googlecode.com/files/muduo-0.2.0-alpha.tar.gz SHA 1 checksum:75 a 09 a 82 f 96 b 583004876 e 95105 c 679 e 64 c 95715
雲の風は彼のブログでネットゲーム接続サーバの機能要件(「練習プロジェクト」を検索)に言及し、私はC++でこれらの需要を初歩的に実現し、muduoネットワークライブラリの例としてセットの自動化test harnessを作成しました.
注意:本明細書で示すコードは、基本的な機能要件のみを実現し、セキュリティを考慮せず、特にパフォーマンスを最適化するものではなく、実際にパブリックネットワーク上で実行されるネットワーク・ゲーム接続サーバとして使用するのに適していません.
機能要件
この接続サーバは、複数のクライアント接続を1つの内部TCP接続に集約し、「データ列並列変換」の役割を果たし、backendの論理サーバがマルチ接続の同時性を考慮することなく業務に専念できるようにする.以下はシステムのブロック図です.

この接続サーバの役割はデジタル回路のデータセレクタ(multiplexer)と似ているので、multiplexerと名付けました.△実はIO-Multiplexingもこの意味で、1つのthread-of-controlが複数のIOファイル記述子を選択的に処理できるようにしています.

(上図はwikipediaから取ってpublic domain著作権です)
インプリメンテーション
Multiplexerの機能要件は複雑ではなく、backend connectionとclient connectionsの間でデータを逆騰させることにほかならない.具体的には、主に4つのイベントを処理します.
実装には、次の2つの点に注意してください.
最初の問題はstd::map〈int,TcpConnectionPtr〉clientConns_;idからclient connectionへのマッピングを保存すればいいです.
2つ目の問題は似たような方法で解決できますが、muduo::net::TcpConnectionのcontext機能を紹介したいと思います.各TcpConnectionにはboost::anyメンバーがあり、顧客コードによって自由に支配されます(get/set).コードは以下の通りです.このboost::anyはTcpConnectionのcontextで、接続にバインドされた任意のデータ(例えば、接続ID、接続の最終データ到着時間、接続に代表されるユーザの名前など)を保存するために使用できます.これにより、クライアントコードはTcpConnectionを継承する必要がなく、attach自身の状態をattachすることができ、TcpConnectionFactoryも使用できません.(継承が許可されている場合は、必ずTcpServerにこのfactoryを注入します).
class TcpConnection : public boost::enable_shared_from_this<TcpConnection>,
boost::noncopyable
{
public:
void setContext(const boost::any& context)
{ context_ = context; }
boost::any& getContext()
{ return context_; }
const boost::any& getContext() const
{ return context_; }
// ...
private:
// ...
boost::any context_;
};
typedef boost::shared_ptr<TcpConnection> TcpConnectionPtr;
Multiplexerの場合、onClientConnection()でconn->setContext(id)を呼び出し、TcpConnectionオブジェクトにidを格納します.onClientMessage()はTcpConnectionオブジェクトからidを取得し、データとともにbackendに送信し、以下のように完全に実現される.
void onClientMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp)
{
if (!conn->getContext().empty())
{
int id = boost::any_cast<int>(conn->getContext());
sendBackendBuffer(id, buf);
}
else
{
buf->retrieveAll();
}
}
Multiplexerはバイナリプロトコルですが、どのようにテストしますか?
テストの自動化
Multiplexerはmuduoネットワークプログラミングの例の中で初めてnon-trivialビジネスロジックを持つネットワークプログラムで、陳碩の「分散プログラムの自動回帰テスト」の一文の思想に基づいて、私はそれのためにtest harnessを編纂しました.コードはhttp://code.google.com/p/muduo/source/browse/trunk/examples/multiplexer/harness/src/com/chenshuo/muduo/example/multiplexerを参照
このTest harnessはJavaで作成され、Nettyライブラリを使用しています.このtest harnessはclientsとbackendを演じ、つまり積極的に接続を開始するだけでなく、受動的に接続を受け入れなければならない.またtest harnessとmultiplexerの起動順序は任意ですので、どうすればいいかコードを読んでください.構造は次のとおりです.

Test harnessは様々なeventをblocking queueに集め、test caseの作成を容易にします.Test caseはtest harnessを操作し、接続を開始し、データを送信し、受信したデータをチェックします.例えば、以下はいずれかのtest caseです.
http://code.google.com/p/muduo/source/browse/trunk/examples/multiplexer/harness/src/com/chenshuo/muduo/example/multiplexer/testcase/TestOneClientSend.java
ここでいくつかのtest casesはjavaで直接書かれていますが、必要であればGroovyで書くこともできます.これにより、test harnessを再起動せずにいつでもtest casesの追加を変更することができます.具体的なやり方は陳碩の『「ファミリー」版のモバイルオフライン課金システムの実現』を参照してください.
将来の改善は、この自動化されたtest harnessがあり、multiplexerを比較的便利かつ安全に修正(さらには再設計)することができます.例えば、