Python中实现远程调用(RPC、RMI)简单例子

yipeiwu_com6年前Python基础

远程调用使得调用远程服务器的对象、方法的方式就和调用本地对象、方法的方式差不多,因为我们通过网络编程把这些都隐藏起来了。远程调用是分布式系统的基础。

远程调用一般分为两种,远程过程调用(RPC)和远程方法调用(RMI)。

RPC

RPC属于函数级别的远程调用,其多是通过HTTP传输数据,数据形式有XML、JSON、序列化数据等。在此,用python做一个xml-rpc的示例。 先给服务器端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是一个绑定了本地8080端口的服务器对象,register_function()方法将函数add注册到s中。serve_forever()启动服务器。 再给个客户端client.py:

from xmlrpclib import ServerProxy
if __name__ == '__main__':
    s = ServerProxy("http://127.0.0.1:8080")
    print s.add(3,4)


现在,运行server.py,然后运行client.py,client.py所在的console会输出7。

我们用wireshark看一下这期间传递的数据是什么样子的,请求的数据:

复制代码 代码如下:

<?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>

响应的数据:
复制代码 代码如下:

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

好吧,言简意赅,不做赘述。

RMI

RMI意为远程方法调用,粒度比RPC要大,因为它的基本单位是对象。其大致思路是这样的:创建RMI服务器对象,将实例化的某个对象以指定的服务名称(也可以是多个对象,但是服务名称不应相同)注册到RMI服务器对象中,之后启动RMI服务器。服务器等待客户端发送的数据(包括服务名称、函数名、参数),将处理结果返回给客户端。 Pyro4是一个基于python的RMI实现,下面我们用Pyro4创建一个RMI服务器,请看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变量是Pyro4用自己的方法为greeting_maker对象生成的uri,其中包括套接字以及为greeting_maker生成的唯一的id。这个id相当于服务名称,当然也可以指定更易懂的服务名称。下面是客户端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)


这其中要输入的uri也就是server2.py生成的uri。通过给Pyro4.Proxy传递greeting_maker的uri,可以认为和服务器端的greeting_maker建立的连接,然后调用greeting_maker的get_fortune()方法。如果name是letian,那么print greeting_maker.get_fortune(name)的结果是Hello, letian.。

相关文章

浅谈tensorflow中几个随机函数的用法

如下所示: tf.constant(value, dtype=None, shape=None) 创建一个常量tensor,按照给出value来赋值,可以用shape来指定其形状...

Python 静态方法和类方法实例分析

Python 静态方法和类方法实例分析

本文实例讲述了Python 静态方法和类方法。分享给大家供大家参考,具体如下: 1. 类属性、实例属性 它们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 实例属性属于对...

Python使用get_text()方法从大段html中提取文本的实例

如下所示: <textarea rows="" cols="" name="id"><DIV style="TEXT-INDENT: 18pt; mso-char-...

Python获取航线信息并且制作成图的讲解

Python获取航线信息并且制作成图的讲解

获取航线信息并且制作成图 航线信息 航线信息查询网站 本次实例使用的航班号为 CES5496 查询后在network中可以寻找到如下内容https://zh.flighta...

Django中更新多个对象数据与删除对象的方法

更新多个对象 例如说我们现在想要将Apress Publisher的名称由原来的”Apress”更改为”Apress Publishing”。若使用save()方法,如: >&...