How is a simple RPC framework made (III)-implement RPC call with parameters, rpciii
In the previous article, we developed a simple RPC message format, but there are still two problems left over.
- We didn't implement the corresponding encode and decode methods, instead of directly passing memory variables based on strings that can be transferred across devices.
- Currently, RPC requests do not support request commands with parameters. For example, add (a, B) describes the parameters a and B in RPC messages.
Let me first implement the second problem, that is, the RPC call with parameters.
In fact, there is no big difference. Since a parameter is required, only the original Request message can be extended. A parameter member is added to indicate the parameter. The specific format adopts the dictionary mode, {'arg1', arg1, 'arg2', arg2 ,....}. This solves the problem of multi-parameter representation.
Class Request (object): ''' @ RPC Request, which consists of the command id and Request content. This implementation is related to the specific RPC protocol. @ Here is the simplification. The data structure of the protocol '''def _ init _ (self) is '''constructor ''' self. id = 0 # id is used to bind the Request and Response. self is useful in asynchronous calls. command = None # sayHello self. parameter = {} def _ str _ (self): return ''. join ('Id: ', str (self. id), 'COMMAND: ', str (self. command), 'parameter: ', str (self. parameter )))
Add (a = 1, B = 2) RPC requests look like this
Request : id = 3, command = 'add', parameter = {'a':1, 'b':2}
The client's add method can be written in this way.
def add(self, a, b): req = Request() req.id = 3 req.command = 'add' req.parameter = {'a':a, 'b':b} return self.request(req)
How can the server obtain the parameters after receiving this RPC request? A traditional and slightly clumsy method is:
def add(self, a, b): return a + b def procReqeust__add(self, req): parameter = req.parameter a = parameter.get('a') b = parameter.get('b') return self.add(a, b)
The disadvantage of this method is that you cannot be lazy. (Lazy and lazy) What should I do for every RPC call? I am bored and have no technical skills, but I am still careful, accidentally mistaken the name of a or B.
At this time, the big killer is playing, and the script language is to find a good one. There is always some unexpected convenience. Directly Add code
def procReqeust__add(self, req): parameter = req.parameter return self.add(**parameter)
If you are not familiar with the above ** parameter, go to your mother. Here is a simple explanation: ** parmater works the same way as the clumsy code, but there is a precondition that even if the parameter variable name a and B cannot be changed during the add declaration. (C ++ students may be dizzy, and there is such a saying in voice)
So far, using this new method, our server code is like this. For methods without parameters, the above ** can be safely used.
def procRequest(self,req): rsp = Response() rsp.id = req.id if req.command == 'sayHello': rsp.result = self.sayHello(**req.parameter) elif req.command == 'add': rsp.result = self.add(**req.parameter) else: raise Exception("unknown command")
Over. It's quite satisfactory.
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.