Weibw's World Weibw's World
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Weibw

一个没有梦想的咸鱼
首页
  • HTML
  • Python

    • Python基础知识
    • Python CookBook第三版
    • Flask
  • MySQL

    • MySQL基础知识
    • MySQL调优
    • MySQL面试题
算法
  • FineReport
  • Kettle
  • Git
  • 微信公众号文章
  • 优秀博客文章
  • 其他
收藏夹
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《Flask》

  • 《Python Cookbook》第三版

    • 第一章:数据结构与算法

    • 第二章:字符串和文本

    • 第三章:数字日期和时间

    • 第四章:迭代器与生成器

    • 第五章:文件与IO

    • 第六章:数据编码和处理

    • 第七章:函数

    • 第八章:类与对象

    • 第九章:元编程

    • 第十章:模块与包

    • 第十一章:网络与Web编程

      • 作为客户端与HTTP服务交互
      • 创建TCP服务器
      • 创建UDP服务器
      • 通过CIDR地址生成对应的IP地址集
      • 创建一个简单的REST接口
      • 通过XML-RPC实现简单的远程调用
        • 问题
        • 解决方案
        • 讨论
      • 在不同的Python解释器之间交互
      • 实现远程方法调用
      • 简单的客户端认证
      • 在网络服务中加入SSL
      • 进程间传递Socket文件描述符
      • 理解事件驱动的IO
      • 发送与接收大型数组
    • 第十二章:并发编程

    • 第十三章:脚本编程与系统管理

    • 第十四章:测试、调试和异常

    • 第十五章:C语言扩展

  • Python基础

  • Python
  • 《Python Cookbook》第三版
  • 第十一章:网络与Web编程
weibw
2022-01-18

通过XML-RPC实现简单的远程调用

# 问题

你想找到一个简单的方式去执行运行在远程机器上面的Python程序中的函数或方法。

# 解决方案

实现一个远程方法调用的最简单方式是使用XML-RPC。下面我们演示一下一个实现了键-值存储功能的简单服务器:

from xmlrpc.server import SimpleXMLRPCServer

class KeyValueServer:
    _rpc_methods_ = ['get', 'set', 'delete', 'exists', 'keys']
    def __init__(self, address):
        self._data = {}
        self._serv = SimpleXMLRPCServer(address, allow_none=True)
        for name in self._rpc_methods_:
            self._serv.register_function(getattr(self, name))

    def get(self, name):
        return self._data[name]

    def set(self, name, value):
        self._data[name] = value

    def delete(self, name):
        del self._data[name]

    def exists(self, name):
        return name in self._data

    def keys(self):
        return list(self._data)

    def serve_forever(self):
        self._serv.serve_forever()

# Example
if __name__ == '__main__':
    kvserv = KeyValueServer(('', 15000))
    kvserv.serve_forever()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

下面我们从一个客户端机器上面来访问服务器:

>>> from xmlrpc.client import ServerProxy
>>> s = ServerProxy('http://localhost:15000', allow_none=True)
>>> s.set('foo', 'bar')
>>> s.set('spam', [1, 2, 3])
>>> s.keys()
['spam', 'foo']
>>> s.get('foo')
'bar'
>>> s.get('spam')
[1, 2, 3]
>>> s.delete('spam')
>>> s.exists('spam')
False
>>>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 讨论

XML-RPC 可以让我们很容易的构造一个简单的远程调用服务。你所需要做的仅仅是创建一个服务器实例, 通过它的方法 register_function() 来注册函数,然后使用方法 serve_forever() 启动它。 在上面我们将这些步骤放在一起写到一个类中,不够这并不是必须的。比如你还可以像下面这样创建一个服务器:

from xmlrpc.server import SimpleXMLRPCServer
def add(x,y):
    return x+y

serv = SimpleXMLRPCServer(('', 15000))
serv.register_function(add)
serv.serve_forever()
1
2
3
4
5
6
7

XML-RPC暴露出来的函数只能适用于部分数据类型,比如字符串、整形、列表和字典。 对于其他类型就得需要做些额外的功课了。 例如,如果你想通过 XML-RPC 传递一个对象实例,实际上只有他的实例字典被处理:

>>> class Point:
...     def __init__(self, x, y):
...             self.x = x
...             self.y = y
...
>>> p = Point(2, 3)
>>> s.set('foo', p)
>>> s.get('foo')
{'x': 2, 'y': 3}
>>>
1
2
3
4
5
6
7
8
9
10

类似的,对于二进制数据的处理也跟你想象的不太一样:

>>> s.set('foo', b'Hello World')
>>> s.get('foo')
<xmlrpc.client.Binary object at 0x10131d410>

>>> _.data
b'Hello World'
>>>
1
2
3
4
5
6
7

一般来讲,你不应该将 XML-RPC 服务以公共API的方式暴露出来。 对于这种情况,通常分布式应用程序会是一个更好的选择。

XML-RPC的一个缺点是它的性能。SimpleXMLRPCServer 的实现是单线程的, 所以它不适合于大型程序,尽管我们在11.2小节中演示过它是可以通过多线程来执行的。 另外,由于 XML-RPC 将所有数据都序列化为XML格式,所以它会比其他的方式运行的慢一些。 但是它也有优点,这种方式的编码可以被绝大部分其他编程语言支持。 通过使用这种方式,其他语言的客户端程序都能访问你的服务。

虽然XML-RPC有很多缺点,但是如果你需要快速构建一个简单远程过程调用系统的话,它仍然值得去学习的。 有时候,简单的方案就已经足够了。

编辑 (opens new window)
上次更新: 2023/10/13, 17:39:25
创建一个简单的REST接口
在不同的Python解释器之间交互

← 创建一个简单的REST接口 在不同的Python解释器之间交互→

最近更新
01
牛客网非技术快速入门SQL练习题
03-08
02
其他日常SQL题
03-07
03
用户与权限管理
03-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 | Weibw | 辽ICP备18015889号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式