プロトコル設計

プロトコルセットの固定

nineマッチングサーバーフレームワークでは、固定的なプロトコルセットを提供している。 フレームワーク利用の際には、各プロトコルに対するアクションを記述することで行う。

プロトコルを拡張したい場合は、後述する NestMessage と MessageExtension の二つの仕組みで行うことができる。

Request, Response, Notify

プロトコルは Request-Response 対と Notify という二種三個のメッセージタイプに分けられる。

Request
何らかの処理を要求するタイプのメッセージ。必ず Response が返る。
Response
Request に対する応答。成功/失敗の通知を行う。Request は内容に応じた別々のクラスが定義されているが、Response クラスは単一である。
Extension 機構を利用して、簡単な情報を付けくわえることができる。
ある程度以上の情報を渡す必要がある場合は、次の Notify を用いる。
Notify
自律的に、または Request をトリガーとして、情報を通知する際に用いる。

このプロトコル設計に特徴的な部分は、Request に対して Response と Notify という二つの応答が返るところである。ネットワーク効率は悪くなるが、Client-Pull, Server-Push の両方の通信形式にひとつのコードで対応できる利点がある。

例えば、Client-Pull 型のログイン処理は次のようなフローになる:


  1. クライアントがサーバーへ、LoginRequest を投げる。
  2. サーバーは、LoginResponse を返す。
  3. サーバーは、LoginNotify を返す。
  4. クライアントは LoginNotify を見て、ログイン完了処理を行う。

Server-Push による自動的なログインは次のようになる。


  1. サーバーはクライアントへ LoginNotify を投げる。
  2. クライアントは LoginNotify を見て、ログイン完了処理を行う。

ここで、クライアントのログイン処理のコードは共通にできる。

MessageExtension

フレームワークの定義するメッセージの多くは、MessageExtension というクラスを継承している。これは定義されたメンバ以外のデータを含める際に使うことができる。

例えば、8bit整数の情報を加えたいとすると、送信側は次のように記述する。

LoginRequest msg;
msg.extSetInt8(0, 0xFF);

受信側では、次のように記述して拡張情報を受け取ることができる。

bool MyModule::handleClientLogin(LoginRequest* pMsg, ...)
{
  int8 myext;
  pMsg->extGetInt8(0, &myext);
}

ここで extSetInt8, extGetInt8 の両関数の第一引数に使用した 0 は、拡張データの ID である。重複しないよう、アプリケーション側で管理する必要がある。

具体的な使い方は、チュートリアルの SampleOpenRoomRequestの説明を参照のこと。

NestMessage

フレームワークでは、汎用的に使える NestMessage という種類のメッセージをいくつか定義している。

NestMessage は、内部に他の nine::Message を含めることができるメッセージである。内部メッセージは nine::Message のサブクラスなら何でもよく、実質的にどんなメッセージも含めることができる。

extension による既存メッセージの拡張では不十分で、新規メッセージを追加したいような場合は、このメッセージを用いることができる。

現在提供されている NestMessage は以下のものがある:


拡張モジュールにこれらのメッセージを扱う仮想関数が定義されている。NestMessage を使う場合はこれらの関数をオーバーライドして実装する。