Client-Server Communication
When a client connects to a server, communication is first established over TCP.
In the meantime, if a successful UDP holepunch to the server occurs in the background, UDP communication is possible, but until then, both reliable, unreliable messaging is replaced by TCP. However, after a successful UDP holepunch, reliable messaging is replaced by UDP.
Clients each have a TCP port and a UDP port, and the server has one TCP listening port and one or more UDP ports. Clients maintain a TCP connection to the server and select one of the server-side UDP ports, meaning that the server shares multiple UDP ports evenly among all connected clients.
For example, if 40,000 clients communicate with a server that has 20,000 open UDP ports, there will be two clients communicating for each UDP port on the server side.
Registering and Using Proxy & Stub Communication Objects
To add communication to the server and client, we will create a Common project that will be used by both the server and client for convenience, and prepare a PIDL file. In the prepared PIDL file, define the protocol for sending communication from the server to the client.
Compiling the above PIDL file will create a Proxy and Stub object.
How to Use Proxy Objects
First, include the Header wherever you want to use it.
Create a proxy and register it with the server object.
We registered it by passing a pointer to the created Proxy object using a function called AttachProxy. AttachProxy can register multiple types of PIDLs by managing them internally as an array. Once registered, you can use the functions of the Proxy object to communicate.
Like proxy, stub includes a header wherever you want to use it.
In the case of the Stub object, you must create and use an inherited object because it is a defining function of the protocol to be received. If you register it using the AttachStub function, it will be called when that call comes in. Inside the generated Stub object, a Define is created, which allows you to avoid having to modify your cpp and h files separately when you change protocols.
Among the define statements specified in the Stub Class, declare DEFRMI_NameSpace_function name in the header file of the inherited object and DECRMI_NameSpace_function name (Class_Name) in the cpp.
Returning 'True' means that it has been processed. If it returns 'False', the OnNoRmiProcessed Event is called because the user has not processed the protocol. Of the function arguments called with DEFRMI_S2C_Chat, remote is the value of the HostID of the other party that called the RMI. By invoking the Proxy with this ID value, you can send communication to the desired party.
Now we will register the Stub object we created with the Client object.
The AttachStub function is also managed internally as an array, and is registered by passing a pointer to it.
Be sure to check your traffic after development. Traffic requires checking the amount of communication on each client, server (and Super Peer if you use Super Peer), etc. and removing unnecessary traffic. To check your traffic, you can use the methods below.
Use a tool like NetLimiter.
There is a way to run exactly as many processes as you want to use on one computer, and then check the number of bytes sent and received per interval in the Task Manager.
You can use ProudNet's internal function CNetServer::GetStats(CNetServerStats &outVal); to get real-time traffic sent and received per second, the number sent or received, and more. If the total traffic from a single client is roughly 20-30 KB or more, you may experience issues with your international service.
Tools like NetLimiter are recommended to be deleted after use. Kernel Hooking puts 20x the original speed burden on the core holding the communication daubers.
Event
- Common to client and server
Using errorInfo -> ToString(); in the parameter errorInfo, you can easily get information about the problem.
- Server
This can be used for performance testing and more.
Last updated