8. サブスクライバー

8.1. はじめに

サブスクライバーとは購読・出版型モデルのメッセージングを行う機能です。 メッセージの送信者は「トピック」と呼ばれる特定の話題を扱うチャンネルに「コンテンツ」を投稿します。 メッセージの受信者は任意のトピックからコンテンツを取得できます。(Figure 8.1)

コンテンツにはコンテンツ ID、任意の文字列 (最大 SubscriberConstants::MAX_CONTENT_MESSAGE_LEN)、 任意のバイナリ (最大 SubscriberConstants::MAX_CONTENT_BINARY_SIZE)、投稿者のプリンシパル ID、投稿先のトピック、投稿日時が含まれます。 一つのコンテンツは複数のトピックに対して投稿できます。 通常の NEX の API はポーリングが禁止されていますが、コンテンツを受信する API に関してはポーリングが認められています。 詳細については 特定のトピックからコンテンツを取得する を参照してください。

_images/Fig_Subscriber_GetContent.png

Figure 8.1 トピックからコンテンツを取得する

以下のような用途を想定しています。

  • あるユーザーが対戦相手を募集するときに「対戦者求む!対戦条件は○×△!」というコンテンツをあるトピックに投稿する。 対戦を希望する他のユーザーはあらかじめそのトピックを監視しておき、気に入った募集を見つけたら対戦を申し込む。
  • データストアでユーザー作成のマップデータをアップロードしたという旨をトピックに投稿し、受信者はそれを新着投稿リストとして扱う。

8.2. サブスクライバー利用の流れ

サブスクライバーを利用する際の流れは以下のようになります。

  1. ゲームサーバーにログインする
  2. サービスクライアントを初期化する ( 8.3. )
  3. トピックにコンテンツを投稿する ( 8.4. )
  4. トピックからコンテンツを取得する ( 8.5. )
  5. サービスクライアントの終了処理を行い、ゲームサーバーからログアウトする。

8.3. サービスクライアントの初期化・終了

利用するサービスクライアントは SubscriberClient です。 SubscriberClient の初期化・終了処理はマッチメイクでのサービスクライアントの初期化・終了処理と同様です( 4.3. )。

8.4. トピックにコンテンツを投稿する

特定の話題についての情報を発信するには SubscriberClient::PostContent() を使いトピックにコンテンツを投稿します。 投稿先のトピックは複数指定できます。必ず一つ以上のトピックを指定する必要があります。 投稿したコンテンツにはコンテンツ ID が割り当てられます。コンテンツ ID は投稿ごとに単調増加する値です。

トピックは以下のフォーマットの文字列で指定します。

"r_<予約済みトピック番号>"

予約済みトピック番号は 0 から SubscriberConstants::NUM_RESERVED_TOPICS - 1 までとなります。 つまり “r_0”, “r_1”, ... , “r_127” が使用可能です。 SubscriberUtil::ReservedTopicNumToTopicString() を使うと予約済みトピック番号からこの文字列を生成できます。 トピック文字列から予約済みトピック番号に変換するには SubscriberUtil::TopicStringToReservedTopicNum() を使用します。

8.5. 特定のトピックからコンテンツを取得する

特定のトピックに投稿されたコンテンツを取得するには SubscriberClient::GetContent() を使用します。 一つのトピックには最大 SubscriberConstants::MAX_TOPIC_CONTENT_SIZE 件のコンテンツが保持されます。

取得したコンテンツはコンテンツ ID 順 (降順) に並びます。 コンテンツ ID は投稿された順に発行され、増加していきますがコンテンツに含まれる投稿日時は数秒前後する可能性があります。 厳密な投稿日時順ではないことにご注意ください。 サーバーでの処理タイミングの差により、過去取得した最大のコンテンツ ID より小さいコンテンツ ID のコンテンツが後で挿入されることがあります。 例えば、コンテンツを取得した際にコンテンツ ID が 3, 1 と並んでいた場合、その後もう一度コンテンツを取得すると 3, 2, 1 と並ぶ可能性があります。

SubscriberClient::GetContent() は例外的にガイドラインに定められた範囲において定期的に呼び出すことが可能です。 呼び出し頻度の制限についてはガイドラインを参照してください。 ポーリングする際は SubscriberGetContentParam::SetMinimumContentId() を用いて前回取得したコンテンツを再度取得しないようにし、 一つのトピックから一度に取得する件数を 20 件以内にしてください。 なお、複数のトピックから一度にコンテンツを取得するオーバーロード関数を用いたポーリングも可能です。 取得した情報を利用しない場面に遷移した場合などはポーリングを停止し、できる限り不要なアクセスを避けるようにしてください。

8.6. 投稿したコンテンツを削除する

自分自身が過去に投稿したコンテンツを削除するには SubscriberClient::DeleteContent() を使用します。 削除するにはコンテンツ ID に加え、トピックを指定する必要があります。 例えば、投稿時にトピックを三つ指定していた場合、全てのトピックからコンテンツを削除するには三つ全てのトピックを指定します。 一つのトピックからのみ削除する場合はトピックを一つ指定します。このとき残りの二つのトピックにはコンテンツが残ります。 他のユーザーが投稿したコンテンツは削除できません。

コンテンツの削除は NMAS からも行えるようになる予定です。

8.7. エラーハンドリング

エラーハンドリングの方法についてはマッチメイクと同じとなりますので、 4.25. を参照してください。 サブスクライバーで発生しうるエラーについては Table 8.1 となります。 これらが発生する API については個々の関数リファレンスに記載されています。 ただし、NEX の通信処理等で発生する共通エラーを除いています。

Table 8.1 サブスクライバーエラー一覧
ReturnCode 値 概要
QERROR(Subscriber, Unknown) 不明なエラー。サーバーで予期せぬエラーが起きた場合に発生する可能性があります。
QERROR(Subscriber, InvalidArgument) 引数が不正。アプリケーションの実装の誤りにより発生します。
QERROR(Subscriber, OverLimit) 投稿したコンテンツに含まれるメッセージやバイナリのサイズが大きすぎる。一度に取得するトピックの数が多すぎる場合に発生します。アプリケーションの実装の誤りにより発生します。
QERROR(Subscriber, PermissionDenied) 自分が投稿したコンテンツではないものを削除しようとした場合に発生します。アプリケーションの実装の誤りにより発生します。
QERROR(RendezVous, DatabaseTemporarilyUnavailable) データベースに一時的にアクセスできない場合に発生します。