A simple example of implementing remote invocation (RPC RMI) in Python

  • 2020-04-02 13:39:39
  • OfStack

Remote invocation makes the objects and methods of the remote server call in much the same way as the local objects and methods, because we hide them all by network programming. Remote invocation is the foundation of distributed systems.

Remote invocation is generally divided into two types, remote procedure call (RPC) and remote method call (RMI).

RPC

RPC belongs to the remote call at the function level, and it mostly transmits data through HTTP in the form of XML, JSON, serialized data, etc. Here's an example of xml-rpc in python. Server.py:


from SimpleXMLRPCServer import SimpleXMLRPCServer   
def add(x, y):
    return x + y    
if __name__ == '__main__':
    s = SimpleXMLRPCServer(('127.0.0.1', 8080))
    s.register_function(add)
    s.serve_forever()
s Is a bound local 8080 Port of the server object, register_function() Method will function add Registered to s In the. serve_forever() Start the server.   Give it to another client client.py : 
from xmlrpclib import ServerProxy
if __name__ == '__main__':
    s = ServerProxy("http://127.0.0.1:8080")
    print s.add(3,4)

Now, run server.py, then run client.py, and the console where client.py resides will output 7.

Let's use wireshark to see what the data passed during this time looks like, the data requested:


<?xml version='1.0' ?>
<methodCall>
    <methodName>
        add
    </methodName>
    <params>
        <param>
            <value>
                <int> 3 </int>
                </value>
        </param>
        <param>
            <value>
                <int> 4 </int>
            </value>
        </param>
    </params>
</methodCall>

Response data:

<?xml version='1.0' ?>
<methodResponse>
    <params>
        <param>
            <value>
                <int> 7 </int>
            </value>
        </param>
    </params>
</methodResponse>

Well, keep it short and to the point.

RMI

RMI, which stands for remote method call, is more granular than RPC because its basic unit is an object. The general idea is to create an RMI server object, register one of the instantiated objects in the RMI server object with the specified service name (it can also be multiple objects, but the service name should not be the same), and then start the RMI server. The server waits for the data sent by the client (including the service name, function name, parameters) and returns the processing results to the client. Pyro4 is a python-based RMI implementation. Now let's create an RMI server with Pyro4. See server2.py:


import Pyro4
class GreetingMaker(object):
    def get_fortune(self, name):
        return "Hello, {0}. n" .format(name)
greeting_maker=GreetingMaker()
daemon=Pyro4.Daemon()                
uri=daemon.register(greeting_maker)   
print "Ready. Object uri =", uri      
daemon.requestLoop()
uri A variable is Pyro4 In your own way greeting_maker Object generated uri , which includes the socket and the greeting_maker Generated uniquely id . this id Equivalent to the name of the service, but you can also specify a more understandable service name. Here is the client side client2.py : 
import Pyro4
uri=raw_input(" Pyro uri : ").strip()
name=raw_input("Your name: ").strip()
greeting_maker=Pyro4.Proxy(uri)        
print greeting_maker.get_fortune(name)

The uri to enter is the uri generated by server2.py. By passing the uri of greeting_maker to pyro4.proxy, you can think of a connection to the server-side greeting_maker, and then call the get_fortune() method of greeting_maker. If the name is letian, the result of print greeting_maker.get_fortune(name) is Hello, letian.


Related articles: