Controller API に慣れるために、何もしないコントローラを作成する。
class PlainCtrl: public nine::Controller
{
public:
PlainCtrl();
virtual ~PlainCtrl();
virtual int getAttachmentSize() const;
virtual void init();
virtual void beginEncode(Context* pCtx);
virtual void writeEncodeAttachment(Buffer* out, Context* pCtx);
virtual int encode(Buffer* out, Buffer* in, int size, Context* pCtx);
virtual void endEncode(Context* pCtx);
virtual void beginDecode(Context* pCtx);
virtual void readDecodeAttachment(Buffer* in, Context* pCtx);
virtual int decode(Buffer* out, Buffer* in, int size, Context* pCtx);
virtual void handleControlMessage(Message* pMsg, Context* pCtx);
virtual void endDecode(Context* pCtx);
};
何もしないコントローラなので、基本的に関数の中身は空になる。 しかし、最低限実装しなければならない部分がいくつかある。
コントローラを使うと、デフォルトで通常メッセージを拒否するようになる。明示的に許可を与えなければならない。
encode, decode は入力と出力バッファが別になっている。 入力バッファの内容をそのまま出力バッファへ書きこむ必要がある。
void PlainCtrl::init()
{
enableNormalMessage(true);
}
Buffer操作を使うので、分からない場合はドキュメントを見ること。
int PlainCtrl::encode(Buffer* out, Buffer* in, int size, Context*)
{
int ret = 0;
nine::Buffer::IoVec iov;
while (0 < size && 0 < in->getReadBuffers(&iov, 1)) {
if (size < iov.size) { iov.size = size; }
in->skipRead(iov.size);
out->writeArray(iov.ptr, iov.size);
ret += iov.size;
size -= iov.size;
}
return ret;
}
サンプルコントローラは ctrlServer.h で実装されている。 サンプルはテンプレートクラスになっているが、ここではテンプレートを展開した形で引用する。
Communicator::setController() を呼ぶ時、Communicator は接続されている必要はない。 MessageServer::initialize() の中で設定してしまう。
virtual bool initialize(Config* pCfg)
{
if (! super::initialize(pCfg)) { return false; }
int n = pCfg->nCommunicators;
m_ctrls = new PlainCtrl[n];
for (int i=0; i<n; ++i) {
setController(i, &m_ctrls[i], true);
}
return true;
}
setController の第三引数の真偽値は、nine 内部のエンコードを行うかどうかである。 現実装は単なる SHA256 を付け加えてるだけであまり意味はない。 将来的にはデフォルトの暗号化とMACを実装する予定である。
何もしないコントローラの実装・使用方法は以上である。