RPC (remote Procedure call Protocol)-a remoting protocol that requests services from a remote computer program over a network without needing to know the underlying network technology. The RPC protocol assumes that some transport protocols exist, such as TCP or UDP, to carry information data between communication programs. In the OSI network communication model, RPC spans the transport and application tiers. RPC makes it easier to develop applications that include distributed, multi-program networks. RPC takes client/server mode. The requestor is a client, and the service provider is a server.
First, the client call process sends a call message with process parameters to the service process, and then waits for the reply message. on the server side, the process stays asleep until the call information arrives. When a call arrives, the server obtains the process parameters, evaluates the result, sends a reply message, and then waits for the next invocation information , and Finally, the client invokes the process to receive the reply message, obtains the process result, and then invokes execution to proceed.
The above excerpt from, Baidu Encyclopedia.
The first question is why? With a specific protocol definition, we can break out of a regular protocol definition. The process of using a common protocol to reach a remote invocation.
A second question agreement? We chose the JSON protocol, which has the advantage of being flexible and using a string to represent all objects.
The disadvantage is that the resolution is slightly slower, because there is no length identification, so can not search, only one-time parsing. But the exchange of scenes, this is not a problem.
Here is the protocol definition:
Request Definition:
public partial class Requestobj { //<summary>///command (usually method name)/// </summary> public string cmd {get; set;} <summary>///namespace/// </summary> public string ns {get; set;} <summary>///Parameters/// </summary> public object[] args {get; set;} <summary>//// Request serial number/// </summary> public int CID {get; set;} <summary>//// if WebSocket uses// </summary> public string tk {get; set;} <summary>/// Active version sync, 0 ignore// </summary> public int ver {get; set;}}
Response Targeting:
<summary>///Return data/// </summary> public partial class Responseobj {// < Summary>///Return data Object///</summary> public object result {get; set;} <summary>// whether error message/// default 0 error message/// </summary> public int error {get; set;} //<summary>////// </summary> public int CID {get; set;} <summary>///Difference data/// </summary> public opchangeitem[] opstr{get; set;} }
Questions:
Object, is this an unscientific setting? This way is reserved.
Opchangeitem, what the hell is this? is still retained.
Here we try to make a call construct.
Specific methods:
public class localtest{///<summary>///add a message///</summary>public static void AddMessage (String topic, String messagebody) {//Do nothing here}}
Send message:
{"Args": ["Test", "Message"], "CID": "1", "cmd": "AddMessage", "ns": "Localtest", "TK": null}
From the above we can parse it out
Class Name: Localtest, calling Method name: addmessage, Parameter [Topic:test, Messagebody:message]
By reflection invocation, we are done with the purpose of execution.
Then the return value:
When the call is complete, the message is returned:
{"Result": null, "error": 0, "CID": 1, "opstr": []}
Note: The CID is set up to differentiate the request source from the call, and if you have multiple calls at the same time, then CID takes to differentiate your source to match the return value.
As we can see from the above example, we call a AddMessage method, the server responds, and nothing happens.
Our agreement here, throw aside the Opstr field has been able to fully describe an entire call, because the return value, and the arguments are used by object,
So as long as the type is known, it can be converted to the corresponding parameter and type by JSON, so we can get a specific type without special agreement.
And then we make changes.
public void AddMessage (string topic, String Messagebody,action callback) { try {//This side is encapsulated once, The current method call is wrapped directly into a request and then tagged to determine whether it is local execution,//If local execution is performed, local var __cid = WindNet.RemoteCall.Instance.DoCall (callback, this, "Localtest.addmessage", topic,messagebody); if (WindNet.RemoteCall.Instance.IsLocal | | __cid.islocal) { //The thing that was supposed to be done//here is nothing to do if (callback!=null ) callback (); } If it is a remote call, nothing is done. } catch (Exception) { WindNet.RemoteCall.Instance.DoError (e); throw; } }
First we add a callback parameter, and when the execution is complete, we call callback
Because the network is an unstable thing, if you have been waiting, you may be stuck in the main thread, in the game your rendering can not be done, then we use callback for process processing.
and the handling of the return value.
The process is this, you call the function-"construct request-" Launch request-"server returned-" Call Callbak
If we set the islocal to True
Process is
You call the function-"construct request (do not emit)-" execute local Method-"Execute callback
After our design, we had a simple intercept before executing the function, then we matched the callback with the common protocol and CID, and then we reached the correct callback procedure.
Game Programming Series [use of RPC protocol in 1]--game programming