Python的xmlrpc库怎么用 实现XML-RPC客户端和服务端

Python的xmlrpc库基于XML和HTTP实现轻量级RPC,服务端用xmlrpc.server(原SimpleXMLRPCServer),支持线程安全与introspection;客户端用ServerProxy调用远程方法,需注意路径、方法名及类型限制。

Python 的 xmlrpc 库(标准库中的 xmlrpc.clientxmlrpc.server)用于实现轻量级的远程过程调用(RPC),基于 XML 编码和 HTTP 传输。它适合简单服务交互,无需复杂协议或依赖第三方包。

XML-RPC 服务端:用 SimpleXMLRPCServer(Python 3.12+ 已弃用,推荐用 xmlrpc.server)

Python 3.3+ 中,SimpleXMLRPCServer 已移入 xmlrpc.server 模块,且支持线程安全(默认单线程,可搭配 ThreadingMixIn 支持并发)。

示例服务端(支持加法、获取时间):

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler
import datetime

可选:限制只响应特定路径(增强安全性)

class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/RPC2',)

def add(x, y): return x + y

def get_time(): return datetime.datetime.now().isoformat()

创建服务器,监听本地 8000 端口

server = SimpleXMLRPCServer(('localhost', 8000), requestHandler=RequestHandler) server.register_function(add, 'calc.add') server.register_function(get_time, 'system.time')

可选:注册内置系统方法(如 system.listMethods)

server.register_introspection_functions()

print("XML-RPC server running on https://www./link/464d0b9d99efb7a4595380d03b7ea164") try: server.serve_forever() except KeyboardInterrupt: print("\nShutting down server.")

说明:

  • register_function(func, name) 将函数暴露为远程可调用方法,name 是客户端调用时用的名称(如 calc.add
  • register_introspection_functions() 启用 system.listMethodssystem.methodHelp 等调试方法
  • 若需多线程处理并发请求,可继承 ThreadingMixIn
from socketserver import ThreadingMixIn

class ThreadedXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): pass

server = ThreadedXMLRPCServer(('localhost', 8000'))

XML-RPC 客户端:用 xmlrpc.client.ServerProxy

客户端通过 URL 创建代理对象,像调用本地函数一样调用远程方法。

import xmlrpc.client

连接服务端(注意路径 /RPC2 必须和服务端一致)

proxy = xmlrpc.client.ServerProxy('https://www./link/464d0b9d99efb7a4595380d03b7ea164')

调用远程方法(自动序列化/反序列化)

result = proxy.calc.add(10, 20) print("10 + 20 =", result) # 输出:10 + 20 = 30

time_str = proxy.system.time() print("Server time:", time_str)

查看可用方法(需服务端启用了 introspection)

methods = proxy.system.listMethods() print("Available methods:", methods)

关键点:

  • URL 必须包含完整路径(如 /RPC2),否则会返回 404
  • 方法名按点号层级调用(proxy.calc.add 对应服务端注册的 'calc.add'
  • 支持基本类型:int、float、str、bool、list、dict、datetime(自动转为 ISO 格式字符串)、None
  • 不支持自定义类、函数、字节流等;二进制数据需用 xmlrpc.client.Binary 包装

传输二进制数据(如图片、文件内容)

XML-RPC 原生不支持 raw bytes,需用 Binary 类封装:

# 服务端增加方法
def upload_data(data_bin):
    data = data_bin.data  # 获取 bytes
    print(f"Received {len(d

ata)} bytes") return len(data)

server.register_function(upload_data, 'file.upload')

客户端调用

with open('test.bin', 'rb') as f: binary_data = xmlrpc.client.Binary(f.read()) proxy.file.upload(binary_data)

常见问题与注意事项

  • Python 版本差异:Python 3.12+ 已完全移除 SimpleXMLRPCServer 别名,必须从 xmlrpc.server 导入
  • 异常处理:网络错误或服务端异常会抛出 xmlrpc.client.FaultConnectionError,建议 try/except 包裹调用
  • 编码限制:所有字符串必须是 UTF-8 兼容(Python str 默认满足),含控制字符可能失败
  • 性能与替代方案:XML-RPC 解析较慢,不适用于高频或大数据量场景;现代项目更倾向 REST(Flask/FastAPI)或 gRPC

不复杂但容易忽略:确保服务端和客户端使用相同路径、方法名大小写一致、参数类型在 XML-RPC 支持范围内。调试时先用 system.listMethods 确认接口可达。