nine では connect による接続も accept による接続も、接続が完了した後の区別は無い。 よって、クライアント側のコードも、サーバーとほぼ同様の形になる。
server が accept しているところを、クライアントは connect するところが違う点である。
サンプルのクライアントはコマンドラインオプションを解析しているので複雑になっているが、 要は接続数を指定しているだけである。 不要な部分を省いて引用する:
nine::MessageServer::Config cfg; cfg.nAcceptors = 0; cfg.nConnector = 1; client.initialize(&cfg);
サーバーは受動的に接続を生成するが、クライアントは明示的に接続を行う必要がある。 サーバー側で MessageServer#listenLater を呼んだように、クライアント側では MessageServer#connectLater を呼べばよい。
void Client::connect()
{
for (int i=0; i<m_cfg.nCommunicators; ++i) {
m_id[i] = connectLater(host, port);
if (m_id[i] < 0) {
return false;
}
}
...
複数の接続を扱うために複雑になっているが、結局は connectLater を呼んでいるだけである。メッセージ送信には Messenger::post を使う。 Messenger は MessageServer の親クラスなので、post関数は MessageServer でも使うことができる。
TestMessage msg;
msg.setString("hello, world.");
int n = 0;
while (true) {
this->turn();
post(m_id[0], &msg);
nine::msleep(1);
}
while 〜 turn 〜 msleep の流れはサーバー側の run() と同じである。 違いは、post() を行っている部分と、その post で使うためのメッセージオブジェクトを用意している部分である。
post() 関数では最初に Communicator の id を渡し、二番目に送信するメッセージオブジェクトを渡す。 実際に送信するのは、以降に呼ばれた turn() である。