Weitere ähnliche Inhalte
Ähnlich wie Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法 (20)
Kürzlich hochgeladen (11)
Unityネットワーク通信の基盤である「RPC」について、意外と知られていないボトルネックと、その対策法
- 8. 7
通信ライブラリの選択
主な選択要素 UNET 3rdParty全般 独自開発
運用形態
基本的にP2P
カスタムすればC/Sでも
殆どC/S 独自仕様による
プロトコル RUDP/WebSocket
TCP/UDP/RUDP
/WebSocket
独自仕様による
通信品質
ほとんど利用者の
環境に依存
UNETの条件+
オンプレ/クラウドサーバの
設置環境が加わる
独自仕様による
開発サポート
Unityのドキュメント
公式フォーラムなど
各社ドキュメント
会社によってはフォーラム
手厚いサポート
自力で何とかしよう
C/S→P2P移行であればUNETが最適なはずだが、旧UnityNetwork同様
放置されがち。3rdParty製であればある程度楽に開発できるしサポート
も充実しているものが多いが、本当に「最適な通信品質」を目指すなら
RPCを独自開発すべき!という「ぶっちゃけ話」をします。
- 10. 9
RPCとは?
RPC = Remote Procedure Call の略。遠隔手続き呼び出し。
通信を介して接続された相手の端末上で動作する、特定のプログラムを呼
び出して実行する方法です。原則的には相手の実行プロセスに含まれる特
定のコードを呼び出して、実行します。
※ Unity/C# では特定のメソッドを呼び出すことになるので、どちらかというと Java にある
「RMI (=Remote Method Invocation)」の呼び名が近いと思いますが、何故か皆さんこぞって
「RPC」と呼んでますので、それに倣います。
Unityでは、公式のUNET を始めとして、
各種サードパーティ製のネットワークライブラリ(弊社製品「MUN」も含
む)では「RPCを主軸に、任意の情報の送受信としてお使いください」と
いう前提で提供されています。
よって、
Unityでリアルタイムネットワークプログラム、といったら、
このRPCを利用することと同義といっても過言ではありません。
- 17. 16
問題:左の箇所を右のように書き換えた場合、
DeepProfile結果はどれだけ違うでしょうか?
void Start() {
Connect();
}
void Update() {
for(int i=0; i<3; ++i)
RPC ("OnRPC", ALL, null);
}
[RPC]
void OnRPC() {
// Nothing.
}
List<Int32> list = new List<Int32>();
void Start() {
for (int i = 0; i < 255; ++i)
list.Add(new Rand.Next());
Connect();
}
void Update() {
for(int i=0; i<3; ++i)
/* send int[255] */
RPC ("OnRPC", ALL, list.ToArray());
}
/* receive object[255] */
[RPC]
void OnRPC(params object[] obj) {
// Nothing.
}
- 20. 19
解消のための組み込み例
void Update() {
for (int i=0; i<3; ++i) {
List<byte> byteArray = new List<byte>();
foreach (Int32 value in list) {
byteArray.AddRange(
BitConverter.GetBytes(value));
}
RPC("OnRPC", ALL, byteArray.ToArray());
}
}
[RPC]
void OnRPC(byte[] obj) {
List<Int32> intList = new List<Int32>();
for (int index = 0; index < obj.Length; index += 4) {
intList.Add(BitConverter.ToInt32(obj, index));
}
// Anything to do.
}
.NET 3.5 での事例です。
C#6.0 /.NET 4.5以降であれば、これよりも効率的な組み込みが可能です。
- 25. 24
単純にこれだけで重くなります
public class Test {
/* 10000個のRPCメソッドを実装 */
[RPC]
void OnRPC_0000() {
// Nothing.
}
[RPC]
void OnRPC_0001() {
// Nothing.
}
…
[RPC]
void OnRPC_9999() {
// Nothing.
}
void Update() {
RPC ("OnRPC_0001", ALL, null);
}
}
- 27. 26
目的別にRPCを量産したい場合の代替策
public class Test {
/* OnRPC_0000() ~ OnRPC_9999() には [RPC] を付けない! */
void OnRPC_0000() { … }
void OnRPC_0001() { … }
void OnRPC_0002() { … }
…
void OnRPC_9999() { … }
[RPC]
void OnRPC(UInt32 type) {
switch(type) {
case 0: { OnRPC_0000(); } break;
case 1: { OnRPC_0001(); } break;
case 2: { OnRPC_0002(); } break;
....
case 9999: { OnRPC_9999(); } break;
}
}
void Update() {
RPC (“OnRPC”, ALL, 1); /* OnRPC_0001() をコール */
}
}