ProudNet.Cn
WebsiteProud ConsoleLanguage
  • 🌐ProudNet
    • ProudNet 簡介
    • 下載並安裝
      • ProudNet授權認證方法
      • AMI
    • 項目設定
      • C++
      • C#
      • Mac Xcode
      • Linux
      • Unity3D
        • iOS 建置
      • Unreal Engine 4
      • 運行 PIDL 編譯器
    • 使用 ProudNet
      • 伺服器和客戶端
        • 如何使用伺服器
        • 如何使用客戶端
      • RMI
        • 如何使用RMI
      • PIDL
        • 如何使用PIDL
      • 事件處理
      • 通訊訊息
      • P2P 通訊
        • 如何使用P2P通訊
    • 活用 ProudNet
      • 如何使用它
      • 性能小貼士
    • 在 ProudNet 中使用 DB
      • DB Cache System ver.2
        • DB Cache 理論和理解
        • DB Cache 安裝和網絡設置
        • DB Cache 伺服器和用戶端
        • DB Cache 使用與活用
          • DB Cache 活用法
      • ADO API
      • ODBC API
    • ProudNet 實用程式
  • ProudNet note
    • 技術說明
      • 對主循環的理解
      • 配置服務器防火牆
      • 加密和解密
      • 發生錯誤時的應對事項
      • 錯誤信息列表
      • 同步角色位置
      • 客戶端與服務器通信
      • MiniDump (Error Dump System)
      • [1.6 版本] 服務器間 LAN 通訊器
    • 詞彙表
    • Sample 例題
  • 🌐ProudChat
    • 介紹及使用指南
    • 下載 SDK
      • C++
      • C#
      • Unity3D
      • Unreal Engine 4
Powered by GitBook
On this page
  • 為每個 RMI 函數指定單獨的 ID
  • 維持舊的發送和接收方式
  • - 無需 RMI 即可發送和接收自訂訊息
  • - 使用 RMI 參數發送和接收使用者定義的訊息
  • 存取所有 RMI 呼叫點
  • - 從發送方(Proxy)存取呼叫點
  • - 存取接收方(Stub)呼叫點
  • 隱藏 RMI 名稱
  • 返回
  1. ProudNet
  2. 使用 ProudNet
  3. RMI

如何使用RMI

為每個 RMI 函數指定單獨的 ID

global {} 中的 RMI 函數被指派了序列值 RMI ID。

若要取得所需的 RMI ID 值,請參閱下方的 [id=xxx] 語法。

global MedivalWorld 10000
{
    Foo([in] int x);                   // id=10001 自動分配
    [id=13000] id=Foo2([in] int y);    // 強制指定為 id=13000
}

維持舊的發送和接收方式

將ProudNet引入使用過去的發送/接收處理方法建立的程式時,建議更改為RMI方法。 它可以防止程式設計師錯誤地建立發送/接收例程而犯錯,使以後的開發更加方便。

但是,如果您確實需要 RMI 以外的舊傳輸/接收處理方法,我們提供以下替代方法。

- 無需 RMI 即可發送和接收自訂訊息

以下函數用於在不使用Remote Method Invocation的情況下傳送使用者定義的訊息。

傳送
接收回呼

Proud.CNetClient.SendUserMessage

Proud.INetClientEvent.OnReceiveUserMessage

Proud.CNetClient.SendUserMessage

Proud.INetServerEvent.OnReceiveUserMessage

Proud.CLanClient.SendUserMessage

Proud.ILanClientEvent.OnReceiveUserMessage

Proud.CLanServer.SendUserMessage

Proud.ILanServerEvent.OnReceiveUserMessage

傳送
接收回呼

Nettention.Proud.NetClient.SendUserMessage

Nettention.Proud.NetClient.ReceivedUserMessageHandler

Nettention.Proud.NetServer.SendUserMessage

Nettention.Proud.NetServer.ReceiveUserMessageHandler

- 使用 RMI 參數發送和接收使用者定義的訊息

// 在ProudNet中,Proud.ByteArray類型 
// 可以用作RMI參數,如下所示。
Foo([in] Proud::ByteArray something);

// --- PIDL 到這裡

// 這允許您使用過去的傳輸和接收處理例程。
// 傳送訊息時,將在過去的訊息傳送例程中建立的緩衝區物件插入 Proud.ByteArray 物件中。
// 然後,Proud.ByteArray 物件作為 RMI 的參數發送。

// 建立訊息對象
Proud::CMessage msg;
 
/* 使用者建立的 msg 物件尚未指定使用哪個緩衝區。
在這些情況下,您必須呼叫 UseInternalBuffer 才能使 << 運算子發揮作用。
UseInternalBuffer 假定 msg 物件中未指定緩衝區使用。
因此,如果已指定緩衝區使用情況,則不應呼叫此方法。
有關更多詳細信息,請參閱 Proud.CMessage.UseInternalBuffer 幫助。*/
msg.UseInternalBuffer();
 
msg << a << b;
 
Proud::ByteArray block;
block.SetCount(msg.GetLength());
memcpy(block.GetData(), msg.GetData(), block.Count);
 
Foo(Proud::HostID_Server, Proud::RmiContext::ReliableSend, block);

// 接收訊息時,Proud.ByteArray 物件作為開發人員實作的 RMI 函數內的 RMI 參數被接收, 
// 提取您需要的資料。

DEFRMI_MyPIDL_Foo(MyClass)
{
    // Parameter 'block' and the others are is given
    Proud::CMessage msg;
    msg.UseExternalBuffer(block.GetData(), block.Count);
    msg.SetLength(block.Count);
    msg >> a >> b;
    ...
}
// 要在 C# 中使用 ByteArray,必須在 PIDL 中設定它,如下所示。
rename cs(Proud::ByteArray, Nettention.Proud.ByteArray);

// 在ProudNet中,Proud.ByteArray類型 
// 可以用作RMI參數,如下所示。
Foo([in] Proud::ByteArray something);

// --- PIDL 到這裡

// 訊息發送範例
string msg = "Welcome";
byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
Nettention.Proud.ByteArray ar = new Nettention.Proud.ByteArray(msgBytes);

simpleProxy.Foo(Nettention.Proud.HostID.HostID_Server, Nettention.Proud.RmiContext.ReliableSend, ar);

// 接收訊息時,Proud.ByteArray 物件作為開發人員實作的 RMI 函數內的 RMI 參數被接收, 
// 提取您需要的資料。

simpleStub.Foo = (remote, rmi, somthing) => {
    string msg = Convert.ToBase64String(somthing.data);
};

存取所有 RMI 呼叫點

ProudNet 有一個可以存取 RMI 呼叫時間的設備。

  • 記錄所有 RMI 調用

  • 透過測量每個 RMI 的執行時間來優化遊戲伺服器效能

- 從發送方(Proxy)存取呼叫點

1. 首先,為 PIDL 編譯器輸出建立一個 Proxy 衍生類別。 2. 覆蓋NotifySendByProxy

這將導致在每次發送時調用重寫的方法。

預設情況下,NotifySendByProxy()被設定為被調用, 為了進一步提高效能,如果您想要阻止 NotifySendByProxy() 呼叫本身,請將 m_enableNotifySendByProxy 設為 false,這樣 NotifySendByProxy() 將不再被呼叫。

- 存取接收方(Stub)呼叫點

1. 將Stub實例的成員變數m_enableStubProfiling(enableStubProfiling)設為true。 2. 重寫 PIDL 編譯器輸出的 Stub 衍生類別中的 BeforeRmiInvocation 和 AfterRmiInvocation。

這將導致每次接收時都呼叫重寫的方法。

BeforeRmiInvocation 在 RMI 執行即將到來之前調用,AfterRmiInvocation 在執行結束時調用。 這可以幫助您找到導致處理時間較長的伺服器效能問題的 RMI。

如何列印從存根接收的RMI函數的所有參數 將Stub實例的成員變數m_enableNotifyCallFromStub設為true並覆寫NotifyCallFromStub。 此方法接收轉換為字串的參數,因此您可以在此處留下日誌。 然而,由於RMI處理性能較低,建議僅在絕對必要時使用它。

在 C# 中,您可以使用定義的委託函數,而無需單獨重寫它。

同樣可以在定義的 Stub 物件中找到變數。

隱藏 RMI 名稱

為了在BeforeRmiInvocation等顯示主機傳送和接收的RMI的名稱,可以將所有RMI的名稱儲存在一個執行檔中。

但是,如果您出於安全原因想要隱藏它,請按照以下步驟操作。

在將 ..._proxy.cpp include在 PIDL 編譯結果中之前,將其定義如下。

#define HIDE_RMI_NAME_STRING

從版本 1.7.36365 開始,出於安全原因,RMI 函數名稱預設不會出現在 IRmiStub.BeforeRmiInvocation 函數中。

為了顯示PIDL編譯結果的代理,在編譯cpp原始檔之前, 它的定義如下。

#define USE_RMI_NAME_STRING


Last updated 1 year ago

🌐
⬅️
返回