客戶端與服務器通信
客戶端連接到服務器後,首先用TCP進行通信。
在此期間,如果通過後臺成功與服務器進行UDP孔穿孔,則可以進行UDP通信,但在此之前,reliable、Unreliable 信息全部被TCP代替。 但是自從UDP打孔成功以後,Reliable 信息就被UDP代替了。
客戶端用各自的TCP端口、UDP端口進行通信,服務器用1個TCP listening port、1個以上的UDP端口進行通信,客戶端在保持與服務器TCP連接的同時,從服務器側的UDP端口中選擇一個。 即,服務器方均勻地共享給連接多個UDP port的所有客戶端。
例如,如果4萬個客戶端與打開2萬個UDP port的服務器進行通信,服務器方面的每個UDP port就有2個客戶端進行通信。
註冊和使用 Proxy & Stub 通信對象
我們將通信添加到服務器和客戶端。 爲了方便起見,在創建服務器和客戶端都使用的Common(公用)方案後,準備PIDL文件。 定義從服務器向客戶端發送通信的協議,用於準備好的PIDL文件。
Global S2C 3000
{
Chat(Proud::StringA txt);
}
編譯上述PIDL文件時,生成Proxy和Stub客體。
如何使用 Proxy 對象
請先將Header包含在您要使用的地方。
// Server: 通過Server ▶ Client
// Server爲了進行呼叫
// 包含 Proxy 對象。
// header file 宣言
// 創建Common項目
// 因爲假設了Common 方案的
// 包含從文件夾創建的文件 。
#include "../Common/S2C_proxy.h"
// 在 cpp 文件中聲明
#include "../Common/S2C_proxy.cpp"
創建Proxy並註冊爲服務器對象。
// 創建對象。
S2C::Proxy g_S2CProxy;
void main()
{
// 在 Server 描述中創建的
// Server 對象。
CNetServer* srv =
ProudNet::CreateServer();
Svr->AttachProxy(&g_S2CProxy);
// 以下省略
}
使用AttachProxy函數,以移交生成的Proxy客體的指針的方式進行註冊。 AttachProxy通過內部排列管理,可以註冊多種PIDL。 如果註冊了,可以使用Proxy客體的函數進行通信。
// HostID 和 RmiContext
// 會自動添加。
// 想要發送到hostID的
// 輸入 Client 的 HostID 值 。
g_S2CProxy.Chat(
hostID,
RmiContext::ReliableSend,
“Send Message”);
與 Proxy 一樣,stub 也會在要使用的地方包含 Header。
Client:
Server ▶ Client,在Client中
包含 Stub 對象以接收呼叫 。
// header file 宣言
// 創建Common項目
// 因爲假定, 所以在Common文件夾中
// 包含創建的文件 。
#include "../Common/S2C_stub.h"
// 在 cpp 文件中聲明
#include "../Common/S2C_stub.cpp"
對於Stub客體,因爲是接收協議的定義函數,所以必須生成並使用繼承的對象。 使用AttachStub函數註冊後,相應呼叫到來時會回電。 生成的Stub客體內會產生定義(Define),如果使用它,即使變更協議,也不需要另外修改cpp文件和h文件。
#define DECRMI_C2S_Chat bool Chat(
Proud::HostID remote,
Proud::RmiContext &rmiContext,
const Proud::StringA txt)
在 Stub Class 中指定的 Define 語句中, DEFRMI_NameSpace_函數名稱在繼承對象的 Header 文件中聲明, DECRMI_NameSpace_函數名稱 (Class_Name) 在 cpp 中聲明。
class CS2CStub : public S2C::Stub
{
public:
// 即使變更Protocol,用戶
// 無需修改class,在stub內
// 已處理爲define文。
// 以" DEFRMI_NameSpace_ 函數名"
// 如果有, 在header 中聲明 。
DECRMI_S2C_Chat;
};
CS2CStub g_S2CStub;
// 'DEFRMI_Protocol分類名_protocol名(
// 繼承的類 name'
// 如果設置爲 , 則在 cpp 中聲明 。
DEFRMI_S2C_Chat(CS2CStub)
{
printf(
"[Client] HostID:%d, text: %s”,
remote,
txt);
// 必須回傳 true
return true;
}
'True' Return意味着已經處理完畢。 如果Return'False',則判斷爲用戶未對協議進行處理,OnNoRmiProcessed Event將返現。 在返回DEFRMI_S2C_Chat的函數因子中,remote是調用RMI的相對HostID值。 使用此ID值調用Proxy,可以將通信發送給您想要的對方。
現在將生成的Stub客體註冊到Client客體。
CNetClient *client
= ProudNet:CreateClient();
client->AttachStub(&g_S2CStub);
// 以下省略
AttachStub函數也在內部進行排列管理,以移交指針的方式進行註冊。
我建議您使用後刪除NetLimiter等工具。 因Kernel Hooking功能,給握住通信設備的核心帶來20倍以上原本速度的負擔。
事件
- 客戶端與服務器通用
使用參數errorInfo的errorInfo-> ToString();可輕鬆獲得有關問題的信息。
OnError
ProudNet內部發生的Error或因使用過程中出現問題而反饋信息。
OnWarnning
對不嚴重但存在潛在問題的信息進行回電。
OnInformation
對內部情況及溯源等信息進行回電。
OnException
回撥內部Exception錯誤信息。
OnNoRmiProcessed
向PIDL宣佈,但Stub未繼承Event或用戶Return false時呼叫。
- 服務器
可用於性能測試等。
OnUserWorkerThreadBegin
User Worker Thread Pool 的 Thread 啓動時被調用 。
OnUserWorkerThreadEnd
User Worker Thread Pool 的 Thread 結束時被調用 。
Last updated