Before we developed a very simple RPC message format, but also left two questions, the last one resolved off one, and left a
- We do not implement the corresponding encode and decode methods, and are not based on the transfer of strings that can be cross-device, but direct memory variables.
- The request command with parameters is not supported by RPC request now. such as Add (A, b), how to describe the parameter, A/b in the RPC message.
let's get rid of this codec problem. The actual RPC application is basically a cross-machine connection, so it is not possible to pass the memory variables directly, which means that the message needs to be encoded into something like a string that can be transmitted across devices. There are many encapsulation protocols for specific RPC messages, and the common ones are based on Xml,json encapsulation. But if abstract, the actual is a codec, the tube you code into what content, it is not encoded can also. The Black Cat White cat, as long as can pass through, is a good cat.
Here I am still a simple principle, focus on Yu Xiaoyi. Take advantage of the two operations in Python. Str and eval. suppose a dictionary msg = {' A ': 1, ' B ': 2}. Then str (msg) = " {' A ': 1, ' B ': 2}", note that it becomes a string. then eval (" {' A ': 1, ' B ': 2}")-->msg, do an eval operation and change from string to dictionary variable. when encoding, the RPC message is converted to dict and then called STR encoded into a string. when decoding, first call eval to get the Dict object and then convert it to a specific RPC message object
The design is fixed and the rest is just code filling. first modify the previous request's Str method, and return a dict string representation. I do the same thing with response.
Class Request (object): def __str__ (self): return str ({' id ': self.id, ' command ': Self.command, ' Parameter ': Self.parameter})
Then introduce the Encode method
@classmethod def encode (CLS, message): if isinstance (message, Request): return str (message) elif Isinstance (Message, Response): return str (message) elif isinstance (Message, Notification): return str ( Message) else: raise Exception (' unknown type when encode ')
Similarly, the introduction of the Decode method is slightly more complicated. The main trouble is how to differentiate between the decoded response or the request.My method is more speculative, directly according to the contents of the dictionary to judge. The command field must be request, and there must be a result field of response
@classmethod def decode (CLS, data): info = eval (data) if ' command ' in info: request = Request () Request.id = info.get (' id ') request.command = info.get (' command ') request.parameter = info.get (' parameter ', { }) return request elif ' result ' in info: response = response () response.id = info.get (' id ') Response.result = info.get (' result ') return response elif ' message ' in info: note = Notification () note.message = info.get (' message ') return note else: raise Exception (' unknown data when Decode ')
In addition, the client and server code to make a slight adjustment, that is very simple, call the above method is possible, here is not posted.OVER,RPC News This piece, we completely finished. Summary:
- The definition of request and resonse can remain unchanged,
- Encode and Decode methods, such as Bajau, can be ever-changing. If you use XML or JSON or other descriptions, simply customize the encode and Decode methods to
- From a higher level, the RPC message is actually a description of the function call, so at best it is view. Since it is view, the actual degree of freedom is very large.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
How a simple RPC framework is refined (IV)--Implementing the codec of RPC messages