PlainControl

PlainControl

Controller API に慣れるために、何もしないコントローラを作成する。

クラス定義

まずは nine::Controller を継承したクラスを定義する。
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 でのデータコピー

encode, decode は入力と出力バッファが別になっている。 入力バッファの内容をそのまま出力バッファへ書きこむ必要がある。

通常メッセージの許可

init() で行う。
void PlainCtrl::init()
{
   enableNormalMessage(true);
}

encode, decode でのコピー

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;
}

コントローラの登録

作成したコントローラを使うには、Communicator に登録する必要がある。次の手順で登録する:
  1. Controllerオブジェクトを作り
  2. Communicator::setController() で登録する

サンプルコントローラは 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を実装する予定である。

何もしないコントローラの実装・使用方法は以上である。