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 相关文章推荐
pytyon 带有重复的全排列
Aug 13 Python
由Python运算π的值深入Python中科学计算的实现
Apr 17 Python
在Python中操作时间之tzset()方法的使用教程
May 22 Python
python结合API实现即时天气信息
Jan 19 Python
Python中的条件判断语句与循环语句用法小结
Mar 21 Python
Python正规则表达式学习指南
Aug 02 Python
TensorFlow入门使用 tf.train.Saver()保存模型
Apr 24 Python
Ubuntu下升级 python3.7.1流程备忘(推荐)
Dec 10 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
Apr 11 Python
11个Python Pandas小技巧让你的工作更高效(附代码实例)
Apr 30 Python
python3.8.3安装教程及环境配置的详细教程(64-bit)
Nov 28 Python
Python扫描端口的实现
Jan 25 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
PHP下用rmdir实现删除目录的三种方法小结
2008/04/20 PHP
php连接oracle数据库及查询数据的方法
2014/12/29 PHP
PHP整合PayPal支付
2015/06/11 PHP
PHP模板引擎Smarty中的保留变量用法分析
2016/04/11 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
Centos7 Yum安装PHP7.2流程教程详解
2019/07/02 PHP
浅谈laravel aliases别名的原理
2019/10/24 PHP
javaScript 判断字符串是否为数字的简单方法
2009/07/25 Javascript
iframe的onload在Chrome/Opera中执行两次Bug的解决方法
2011/03/17 Javascript
jquery实现图片等比例缩放以及max-width在ie中不兼容解决
2013/03/21 Javascript
MyEclipse取消验证Js的两种方法
2013/11/14 Javascript
javascript间隔定时器(延时定时器)学习 间隔调用和延时调用
2014/01/13 Javascript
JavaScript实现的一个计算数字步数的算法分享
2014/12/06 Javascript
js的回调函数详解
2015/01/05 Javascript
js结合正则实现国内手机号段校验
2015/06/19 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
理解Javascript的call、apply
2015/12/16 Javascript
简单实现js选项卡切换效果
2016/02/03 Javascript
微信小程序图片宽100%显示并且不变形
2017/06/21 Javascript
vue项目中跳转到外部链接的实例讲解
2018/09/20 Javascript
koa+jwt实现token验证与刷新功能
2019/05/30 Javascript
vue2之简易的pc端短信验证码的问题及处理方法
2019/06/03 Javascript
Python常见文件操作的函数示例代码
2011/11/15 Python
python3连接kafka模块pykafka生产者简单封装代码
2019/12/23 Python
你应该知道的30个css选择器
2014/03/19 HTML / CSS
CSS3实现鼠标悬停显示扩展内容
2016/08/24 HTML / CSS
大学专科生推荐信范文
2013/11/23 职场文书
班班通项目实施方案
2014/02/25 职场文书
前处理组长岗位职责
2014/03/01 职场文书
2014年“向国旗敬礼”网上签名寄语活动方案
2014/09/27 职场文书
向国旗敬礼活动小结
2014/09/27 职场文书
技术股东合作协议书
2014/12/02 职场文书
2015年“公民道德宣传日”活动方案
2015/05/06 职场文书
实习单位鉴定意见
2015/06/04 职场文书
一文帮你理解PReact10.5.13源码
2021/04/03 Javascript
欧元符号 €
2022/02/17 杂记