Netcode for GameObjectsで大容量データを送受信する
背景
Netcode for GameObjects(NGO) の Custom messages で2KB程度のメッセージを送ろうとしたら、Reading past the end of the buffer
というエラーで送信できなかった。
原因
NGOは com.unity.transport
上に構築した UnityTransport
を利用してクライアント・サーバ間の通信を行っている。どちらもUnityTransportと呼ばれていて分かりづらいが、前者はUnity本体の機能で、後者はNGOの機能。
ベースとなる com.unity.transport
がUDPで通信しているため、MTU(1500 Bytes程度が一般的)を超えるPayloadを1つのPacketで送受信できないのが問題。
対策
Fragmentation
という Payloadを複数のPacketに分割送信する機能 を利用する。
NGOのチュートリアルには書かれていないが、CustomMessagingManager.SendNamedMessage() の引数に NetworkDelivery
というQoSを指定する項目が存在する。
指定可能な NetworkDelibery
は、ここ から選択可能。
- Realiable / Unreliable = メッセージの到着保証を行うかどうか
- Sequenced = メッセージの到着順保証を行うかどうか
- Fragmented = メッセージの分割送受信をサポートするかどうか
今回はメッセージを分割送信したいので、 ReliableFragmentedSequenced
を選べば良い。
余談
RPC
Custom Message
ではなく RPC
にもQoSを設定する項目はあるが、v1.2.0
の時点では Fragmentationに対応していない ようなので、RPC用途であったとしてもMTUを超えるデータ量がある場合は CustomMessageを利用することになりそう。
通信量制御
こちらの記事 に詳述されている通り、通信量が過剰になった際の対処は入っていない。大量にデータを送りすぎると NetworkManagerのQueueが肥大化してGCにKillされてしまうので注意。