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


Posted in Python onApril 28, 2014

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

远程调用一般分为两种,远程过程调用(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.。
Python 相关文章推荐
python自动zip压缩目录的方法
Jun 28 Python
python 实现上传图片并预览的3种方法(推荐)
Jul 14 Python
详解Python学习之安装pandas
Apr 16 Python
python的pytest框架之命令行参数详解(下)
Jun 27 Python
python使用tomorrow实现多线程的例子
Jul 20 Python
简单的Python调度器Schedule详解
Aug 30 Python
Python输出指定字符串的方法
Feb 06 Python
对Python 字典元素进行删除的方法
Jul 31 Python
Python爬虫防封ip的一些技巧
Aug 06 Python
详解selenium + chromedriver 被反爬的解决方法
Oct 28 Python
python RSA加密的示例
Dec 09 Python
如何利用python实现列表嵌套字典取值
Jun 10 Python
Python的ORM框架SQLObject入门实例
Apr 28 #Python
django自定义Field实现一个字段存储以逗号分隔的字符串
Apr 27 #Python
python监控网卡流量并使用graphite绘图的示例
Apr 27 #Python
python抓取网页图片示例(python爬虫)
Apr 27 #Python
python实现sublime3的less编译插件示例
Apr 27 #Python
python中的实例方法、静态方法、类方法、类变量和实例变量浅析
Apr 26 #Python
Python设计模式之单例模式实例
Apr 26 #Python
You might like
Zend Studio for Eclipse的java.lang.NullPointerException错误的解决方法
2008/12/06 PHP
php imagecreatetruecolor 创建高清和透明图片代码小结
2010/05/15 PHP
php中XMLHttpRequest(Ajax)不能设置自定义的Referer的解决方法
2011/11/26 PHP
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
PhpStorm本地断点调试的方法步骤
2018/05/21 PHP
How to Auto Include a Javascript File
2007/02/02 Javascript
jquery实现手机发送验证码的倒计时代码
2014/02/12 Javascript
Javascript函数式编程语言
2015/10/11 Javascript
解决jquery无法找到其他父级子集问题的方法
2016/05/10 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
JavaScript基础——使用Canvas绘图
2016/11/02 Javascript
详解vue使用vue-layer-mobile组件实现toast,loading效果
2018/08/31 Javascript
JavaScript使用面向对象实现的拖拽功能详解
2019/06/12 Javascript
axios封装与传参示例详解
2020/10/18 Javascript
python采用requests库模拟登录和抓取数据的简单示例
2014/07/05 Python
python通过Windows下远程控制Linux系统
2018/06/20 Python
python用列表生成式写嵌套循环的方法
2018/11/08 Python
python 利用pandas将arff文件转csv文件的方法
2019/02/12 Python
Python测试模块doctest使用解析
2019/08/10 Python
Python常用数据类型之间的转换总结
2019/09/06 Python
基于python判断目录或者文件代码实例
2019/11/29 Python
pytorch 自定义参数不更新方式
2020/01/06 Python
django 前端页面如何实现显示前N条数据
2020/03/16 Python
Django serializer优化类视图的实现示例
2020/07/16 Python
css3动画效果抖动解决方法
2018/09/03 HTML / CSS
HTML5本地存储之IndexedDB
2017/06/16 HTML / CSS
伦敦最著名的老字号百货公司:Selfridges(塞尔福里奇百货)
2016/07/25 全球购物
美国东北部户外服装和设备零售商:Eastern Mountain Sports
2016/10/05 全球购物
连卡佛中国官网:Lane Crawford中文站
2018/01/27 全球购物
社区优秀志愿者材料
2014/02/02 职场文书
小学生评语集锦
2014/04/18 职场文书
人力资源管理求职信
2014/08/07 职场文书
个人求职意向书
2015/05/11 职场文书
2016护理专业求职自荐书
2016/01/28 职场文书
在HTML中引入CSS的几种方式介绍
2021/12/06 HTML / CSS
vue实现可以快进后退的跑马灯组件
2022/04/08 Vue.js