OmniGRPC データ型と運用設定

このページでは、.protoとBlueprintのデータ型の対応、およびゲームやアプリの運用に必要な設定について説明します。

基本的な使用手順については、クイックスタートを参照してください。

データ型の対応

.protoに書かれたデータ型は、Import時に次のBlueprint用データ型へ変換されます。

.protoの型Blueprintで作られる型
doubledouble
floatfloat
int32 / sint32 / sfixed32int32
int64 / sint64 / sfixed64int64
uint32 / fixed32int64
uint64 / fixed64int64。非常に大きな値には制限あり
boolbool
stringFString
bytesByte配列(TArray<uint8>)
enumUser Defined Enum
messageUser Defined Struct
repeated TTArray<T>
map<K,V>KeyとValueを持つStructの配列

uint32は、元の値を失わずにBlueprintで扱うためint64へ変換されます。生成されたStructをそのまま使用できるため、追加の変換処理は不要です。

数値とEnumの制限

型/利用箇所保持できる範囲と注意点
uint32/fixed320〜2^32 - 1をint64で保持
uint64/fixed640〜2^63 - 1。2^63以上はBlueprintのint64で保持できない
生成Struct内のEnumフィールドBlueprintのByte表現により0〜255。負数や256以上の値は保持できない

Enumアセット自体が値を持っていても、生成Structのフィールドを通すとByteの範囲に制限されます。サーバー側の定義に範囲外の値がある場合は、スキーマやデータの受け渡し方を調整してください。

oneof

oneofは、複数の項目のうち1つだけを選んで送る仕組みです。生成されたStructには、選択中の項目を示す<oneof_name>_caseと、それぞれの値を入れる項目が作られます。caseが0の場合は何も選ばれていません。

送信するときは、caseで使う項目を選び、その項目にも値を設定してください。選ばれていない項目は送信されません。

proto3 optional

optionalは、値が「設定されていない」状態も区別する仕組みです。生成されたStructには、値と一緒にbHas_<field>というBooleanが作られます。値を送る場合は、このBooleanをtrueにします。

たとえば数値が0でも、Booleanがtrueなら「0を設定した」、falseなら「何も設定していない」という違いになります。

値bHas_<field>サーバーへ送る内容
0true値0を設定済みとして送信
0falseフィールドを送信しない
42true値42を送信
42falseフィールドを送信しない

map

.protoのmapは、BlueprintではKeyとValueを持つStructの配列になります。TMapではない点に注意してください。

同じKeyを複数入れた場合は、最後のValueが使われます。配列の順番や同じKeyの重複を残したい場合は、サーバー側の.proto設計を通常の配列に変更する必要があります。

protobufの特殊な型

TimestampやDurationは通常のStructとして扱えますが、Blueprintの日時型へ自動変換されるわけではありません。必要に応じて秒やナノ秒から日時へ変換してください。

google.protobuf.Any、FieldMask、Struct/Value/ListValueには、Blueprint向けの専用変換はありません。これらを使うサーバーへ接続する場合は、サーバー担当者またはプログラマーとデータの扱い方を決めてください。

TLSとmTLS

TLSは、送受信するデータを暗号化する仕組みです。公開するゲームやアプリでは、基本的にTLSを使用してください。mTLSは、サーバーだけでなく接続するアプリ側も証明書を提示する、より厳格な接続方法です。

一般的なTLS接続

Make TLS Channel Configを使用します。Hostには、証明書に登録されているサーバーのドメイン名を設定します。正しいHost名が不明な場合は、サーバー管理者へ確認してください。

社内証明書や自己署名証明書を使う場合

Make TLS Custom Root Channel Configを使い、サーバー管理者から提供されたPEM形式のルート証明書をRootCertificatePemへ設定します。使用する証明書については、サーバー管理者へ確認してください。

mTLS

TLS設定に加えて、ClientCertificatePemとClientPrivateKeyPemを設定します。秘密鍵は、Content Browserのアセット、Blueprintの初期値、ログ、スクリーンショットへ保存しないでください。安全な保存方法は、プロジェクトのサーバー・セキュリティ担当者と決めてください。

画像準備中:TLS/mTLS Channel Config

画像差し替えマーカー

Make OmniGrpc Channel Configを展開し、Security、Root Certificate、Client Certificate、Client Private Key、Authority Overrideの位置を示す。証明書本文と秘密鍵はダミーまたは伏せ字にする。

推奨ファイル名
images/OmniGRPC/production-tls-config.png
代替テキスト
BlueprintでOmniGRPCのTLSとmTLSを設定するChannel Config

Metadata

Metadataは、通常のRequestとは別にサーバーへ渡す追加情報です。認証情報や通信の識別情報などに使われます。サーバーから指定がなければ設定する必要はありません。

文字列を送る場合はKeyとValueを設定します。バイト配列を送る場合は、Keyの末尾を-binにし、bIsBinaryをtrueにしてBinary Valueへ値を設定します。

同じKeyを複数回送ることもできます。サーバーから返されたMetadataをすべて確認する場合は、InitialMetadataEntries/TrailerMetadataEntriesを使います。

空のKeyは使用できません。アクセストークンを送る場合は、Metadataへ手入力せず、Channel ConfigまたはCall OptionsのAccess Tokenへ設定する方法が簡単です。

タイムアウト、接続待ち、キャンセル

設定/操作対象動作
CallノードのTimeout1回のRPC全体秒数で期限を指定。0以下は時間制限なし
bWaitForReady = falseRPC開始時接続が一時的な失敗状態なら、回復を待たずエラーにする
bWaitForReady = trueRPC開始時一時的な接続失敗からの回復を待つ。RPCの期限は引き続き有効
Wait for gRPC Channel ConnectedRPC前の接続確認Readyになるまで待つ。正のTimeout Secondsを指定
Cancel実行中のActionそのRPCの中止を要求する

接続待ちを有効にしても、Timeoutは有効です。接続できないまま待ち続けないように、ボタン操作などから始める通信にはTimeoutを設定してください。

接続待ちノードはOn ConnectedのSuccessで分岐します。失敗時にはOn TimeoutとOn Connected(false)の両方が呼ばれるため、失敗処理を重複させないでください。

データの圧縮とサイズ上限

Channelの設定で、圧縮なし、Deflate、Gzipを選べます。画像、音声、長い文章など、大きなデータを送る場合に利用できます。小さなデータでは圧縮が逆に負担になることがあるため、必要な場合だけ設定してください。

MaxReceiveMessageBytesとMaxSendMessageBytesは、1回に受信・送信できるデータサイズの上限です。大きなデータでResourceExhaustedエラーが出る場合に確認してください。上限を大きくしすぎるとメモリを多く使うため、サーバー側の設定と合わせて調整します。

項目初期値意味
CompressionAlgorithmNone圧縮なし
MaxReceiveMessageBytes-1gRPC標準の受信上限(4 MiB)を使用
MaxSendMessageBytes-1gRPC標準の送信設定を使用

このプラグインの-1は「gRPCの設定を変更しない」という指定です。明示的なサイズを指定する場合はバイト数を設定します。

自動再試行と負荷分散

Retry Policyを設定すると、サーバーへ一時的に接続できなかった場合などに通信を自動で再試行できます。RetryPolicyServiceNameには、acme.user.UserServiceのようにpackage名を含む正式なService名を設定します。

項目初期値/指定例意味
MaxAttempts初期値1初回を含む回数。1では再試行しない
InitialBackoff0.1s最初の待ち時間。単位を含む文字列で指定
MaxBackoff1s待ち時間の上限
BackoffMultiplier2.0待ち時間を増やす倍率
RetryableStatusCodes例 Unavailable再試行の対象。初期値は空
RetryPolicyServiceName例 acme.user.UserServiceMaxAttempts > 1のとき必須

ServiceConfigJsonに値を指定した場合は、構造体のRetry PolicyよりJSONの設定が優先されます。

購入やアイテム付与など、同じ処理を2回行うと問題になる通信には、仕組みを理解せず自動再試行を設定しないでください。

Round Robinは、複数のサーバーへ通信を順番に振り分ける高度な設定です。Hostに1つのIPアドレスだけを指定した場合は効果がありません。利用する場合はサーバー管理者と設定を確認してください。

Channelの管理

Channelは同じサーバーとの通信で再利用します。通信のたびに作成すると、接続処理による負荷が増加します。

複数のLevelで使う場合はGameInstanceなど、必要な期間だけ残る場所の変数へ保存します。ゲーム終了時や接続先変更時にはCloseしてください。Client/Bidi StreamingのActionも、通信中は変数へ保存しておきます。

    flowchart TD
	  Create[Channelを作成・変数へ保存] --> RPC[同じChannelでRPCを実行]
	  RPC --> More{続けて通信するか}
	  More -->|はい| RPC
	  More -->|いいえ| Active{進行中のRPCがあるか}
	  Active -->|中止する| Cancel[各ActionのCancel]
	  Active -->|正常終了を待つ| Wait[終了イベントを待つ]
	  Active -->|ない| Close[Close Channel]
	  Cancel --> Close
	  Wait --> Close

Close Channelは進行中のRPCを中止しません。RPCが保持する内部の接続は、そのRPCが終了するまで残ります。画面を閉じた後に結果が不要なら、ActionごとにCancelしてください。

非同期Actionは実行中に自動で保持されます。ただし、後からSend Message、Close Send、Cancelを呼ぶには、Actionを変数へ保存しておく必要があります。Actionの変数を空にするだけでは通信を中止できません。

対応プラットフォームと注意点

5つのプラットフォームすべてへの対応はFull Editionの機能です。Full Editionでは、同じ.proto、生成アセット、Call gRPCノードを使って、PCとスマートフォン向けに展開できます。Free Editionの対応プラットフォームはWindows(Win64)のみです。

プラットフォーム対応範囲主な確認項目
WindowsWin64ファイアウォールと証明書
Linuxx86-64(Full Edition)使用するLinux環境との互換性
macOSarm64 / x86_64(Full Edition)Apple SiliconとIntel Macに対応。CPUごとのTargetArchitecture設定は不要
Android対応(Full Edition)インターネット権限、端末から接続先への経路、TLS
iOS対応(Full Edition)ATS、アプリ署名、端末から接続先への経路、TLS

対応するUnreal Engineは5.6、5.7、5.8です。使用しているEngineと同じバージョンのFabパッケージを選んでください。

トラブルシューティング

症状/Code確認すること
UnavailableHost/Port、サーバーの起動、ファイアウォール、VPN
DeadlineExceededTimeoutが短すぎないか、サーバーの処理に時間がかかっていないか
UnauthenticatedTokenが設定されているか、有効期限が切れていないか
PermissionDeniedログイン中のユーザーに操作権限があるか
ResourceExhausted送受信するデータがサイズ上限を超えていないか
TLS接続に失敗Host名、証明書の期限、設定したルート証明書、端末の日時
Methodが見つからないServiceとMethodの選択、.proto変更後の再生成
Methodの候補が空ノードを選択してDetailsのMethod Nameを確認。Serviceを編集時に解決できるか、RPC種別に合うノードか
接続待ちの失敗処理が2回動くOn TimeoutとOn Connected(false)の両方へ同じ処理を接続していないか
Close後もRPCの結果が届くClose ChannelはRPCを中止しない。ActionのCancelを使用したか
Request/Responseピンの型が違うServiceとMethodを選び直し、BlueprintをRefresh/Compileする
Client Streamingが完了しない最後にClose Sendを呼んだか
Reflection Importに失敗サーバーがReflectionに対応しているか、Service名、TLS、Timeout

問題が発生した場合は、On ErrorのCodeとMessage、Channel State、Host/Port、選択したService/Methodを確認します。アクセストークン、パスワード、秘密鍵はログやスクリーンショットへ含めないでください。

セキュリティチェックリスト

  • 公開するゲームやアプリではInsecureを使わず、TLSを使っている
  • アクセストークン、パスワード、秘密鍵をログやアセットへ保存していない
  • 通信ごとに適切なTimeoutを設定している
  • 自動再試行しても同じ処理が二重に実行されない設計になっている
  • 送受信サイズの上限が大きすぎない
  • Android/iOSは、Editorだけでなく実機でも接続を確認している