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 Django连接MySQL数据库做增删改查
Nov 07 Python
Python bsddb模块操作Berkeley DB数据库介绍
Apr 08 Python
python方向键控制上下左右代码
Jan 20 Python
python 自定义异常和异常捕捉的方法
Oct 18 Python
python实现图片彩色转化为素描
Jan 15 Python
Scrapy-Redis结合POST请求获取数据的方法示例
May 07 Python
python字典的遍历3种方法详解
Aug 10 Python
tensorflow:指定gpu 限制使用量百分比,设置最小使用量的实现
Feb 06 Python
pytorch实现从本地加载 .pth 格式模型
Feb 14 Python
pyinstaller打包成无控制台程序时运行出错(与popen冲突的解决方法)
Apr 15 Python
vscode配置anaconda3的方法步骤
Aug 08 Python
python中的yield from语法快速学习
Nov 06 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提交表单时判断 if($_POST[submit])与 if(isset($_POST[submit])) 的区别
2011/02/08 PHP
深入Nginx + PHP 缓存详解
2013/07/11 PHP
php自动识别文件编码并转换为UTF-8的方法
2014/06/12 PHP
php多重接口的实现方法
2015/06/20 PHP
php实现的rc4加密解密类定义与用法示例
2018/08/16 PHP
php+js实现裁剪任意形状图片
2018/10/31 PHP
简单的php购物车代码
2020/06/05 PHP
使用Rancher在K8S上部署高性能PHP应用程序的教程
2020/07/10 PHP
PHP autoload使用方法及步骤详解
2020/09/05 PHP
基于jQuery的弹出框插件
2012/03/18 Javascript
PHP和NodeJs开发的应用如何共用Session
2015/04/16 NodeJs
JavaScript中length属性的使用方法
2015/06/05 Javascript
JavaScript中解析JSON数据的三种方法
2015/07/03 Javascript
D3.js中data(), enter() 和 exit()的问题详解
2015/08/17 Javascript
Express的路由详解
2015/12/10 Javascript
详解vue-validator(vue验证器)
2017/01/16 Javascript
vuejs2.0实现分页组件使用$emit进行事件监听数据传递的方法
2017/02/22 Javascript
js省市区级联查询(插件版&amp;无插件版)
2017/03/21 Javascript
JS实现在文本指定位置插入内容的简单示例
2017/12/22 Javascript
基于JavaScript中标识符的命名规则介绍
2018/01/06 Javascript
在Layui中操作数据表格,给指定单元格添加事件示例
2019/10/26 Javascript
Vue根据条件添加click事件的方式
2019/11/09 Javascript
jquery插件实现轮播图效果
2020/10/19 jQuery
python开发之tkinter实现图形随鼠标移动的方法
2015/11/11 Python
python Flask实现restful api service
2017/12/04 Python
Pytorch 数据加载与数据预处理方式
2019/12/31 Python
法国发饰品牌:Alexandre De Paris
2018/12/04 全球购物
英国手机壳购买网站:Case Hut
2019/04/11 全球购物
Diptyque英国官方网站:源自法国的知名香氛品牌
2019/08/28 全球购物
幼儿园教研活动总结
2014/04/30 职场文书
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
离婚协议书的范本
2015/01/27 职场文书
2015年共青团工作总结
2015/05/15 职场文书
协议书格式模板
2016/03/24 职场文书
mysql如何配置白名单访问
2021/06/30 MySQL
Nginx源码编译安装过程记录
2021/11/17 Servers