Python远程调用RPC模块xmlrpclib详解与实战

竹里
竹里
发布时间:2026-10-13 | 3人浏览过
原创

本文详细介绍Python中用于远程过程调用(RPC)的xmlrpclib模块。内容涵盖模块定义、ServerProxy构造函数参数说明、常用系统方法、DateTime与Binary对象处理、Fault错误处理以及MultiCall复合调用机制。通过服务端与客户端的完整代码示例,展示如何构建基于XML-RPC的分布式应用,并提及Python 3中该模块更名为xmlrpc.client。

RPC(Remote Procedure Call Protocol,远程过程调用协议)是一种通过网络请求远端服务器服务的技术。服务器接收请求后执行相应操作,并将处理结果返回给客户端。

该协议采用C/S(客户端/服务器)架构模式。客户端可以像调用本地函数一样,通过类似URL的地址调用远程服务器上的参数,并获取返回结果。

利用RPC技术可以实现系统的分布式架构。它能够将复杂功能分解并部署到多台服务器上执行,同时将计算负载分散到不同服务器,从而有效整合和利用计算资源。

在OpenStack项目中,RPC机制被大量使用以支持其分布式架构需求。

RPC通常使用HTTP作为传输层协议,请求数据格式包括XML、JSON等,本文主要讨论基于XML格式的情况。

涉及的Python模块为:

xmlrpclib

注意:在Python 3环境中,该模块已重命名为xmlrpc.client。

虽然XML-RPC本身安全性有限,但从Python 2.7.9版本开始,HTTPS URL默认启用了证书验证和主机名验证,提升了传输安全性。

ServerProxy类的定义如下:

class xmlrpclib.ServerProxy(uri[, transport[, encoding[, verbose[, allow_none[, use_datetime[, context]]]]]])

1. uri:指定服务端URL地址。

2. transport:传输层实例,可选参数,支持https或http协议。

3. encoding:指定字符编码。

4. verbose:是否开启调试模式。

5. allow_none:控制是否允许传递空值。若设置为True,常量None将被转换为XML格式;若为False(默认),传递None时会抛出TypeError异常。

6. use_datetime:是否启用date/time values记录调用时间,支持datetime.datetime类型,默认值为False。

ServerProxy对象提供了一些默认的系统方法:

1. ServerProxy.system.listMethods():返回远端服务器上可用的方法列表。

2. ServerProxy.system.methodSignature(name):返回指定方法的签名,结果类型为数组。

3. ServerProxy.system.methodHelp(name):返回指定方法的帮助信息。

以下是一个简单的RPC调用示例:

服务端代码:

import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer

def get_power(n,m):
 return n**m

server = SimpleXMLRPCServer(("0.0.0.0", 8081))
print "start service get power on 0.0.0.0 8081..."
server.register_function(get_power, "get_power")
server.serve_forever()

客户端代码:

import xmlrpclib

server_power = xmlrpclib.ServerProxy("http://192.168.137.9:8081/")
print "3**2 = %d" %(server_power.get_power(3,2))
print "2**5 = %d" %(server_power.get_power(2,5))

服务端运行结果:

服务端代码(时间处理示例):

# python xml_server.py 
start service get power on 0.0.0.0 8081...

192.168.137.9 - - [22/May/2017 10:37:47] "POST / HTTP/1.1" 200 -
192.168.137.9 - - [22/May/2017 10:37:47] "POST / HTTP/1.1" 200 -

客户端代码(时间处理示例):

# python xml_client.py 
3**2 = 9
2**5 = 32

xmlrpclib模块还提供了一些辅助类和方法:

class xmlrpclib.DateTime:用于表示时间对象。

具体示例如下:

服务端代码(时间处理):

import datetime
from SimpleXMLRPCServer import SimpleXMLRPCServer
import xmlrpclib

def today():
 today = datetime.datetime.today()
 return xmlrpclib.DateTime(today)

server = SimpleXMLRPCServer(("0.0.0.0", 8081))
print "start service on 0.0.0.0 8081..."
server.register_function(today, "today")
server.serve_forever()

客户端代码(时间处理):

import xmlrpclib
import datetime

s = xmlrpclib.ServerProxy("http://192.168.137.9:8081/")

today = s.today()
converted = datetime.datetime.strptime(today.value, "%Y%m%dT%H:%M:%S")
print "Today: %s" % converted.strftime("%d.%m.%Y, %H:%M")

运行结果:

服务端代码(错误处理示例):

# python rpc_time.py 
start service on 0.0.0.0 8081...

192.168.137.9 - - [22/May/2017 10:43:19] "POST / HTTP/1.1" 200 -

客户端代码(错误处理示例):

# python rpc_time_client.py 
Today: 22.05.2017, 10:43

2. class xmlrpclib.Binary:用于表示二进制对象。

3. class xmlrpclib.Fault:用于表示RPC调用过程中发生的错误对象。

例如:

客户端代码(错误处理):

import xmlrpclib

s = xmlrpclib.ServerProxy("http://192.168.137.9:8081/")
try:
 s.add(2, 5)
except xmlrpclib.Fault as err:
 print "A fault occurred"
 print "Fault code: %d" % err.faultCode
 print "Fault string: %s" % err.faultString

class xmlrpclib.MultiCall(server):提供多个调用的复合调用功能。

具体示例如下:

from SimpleXMLRPCServer import SimpleXMLRPCServer

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

def subtract(x, y):
 return x-y

def multiply(x, y):
 return x*y

def divide(x, y):
 return x/y

def get_power(n,m):
 return n**m

server = SimpleXMLRPCServer(("0.0.0.0", 8081))
print "start service on 0.0.0.0 8081..."

server.register_multicall_functions()
server.register_function(add, 'add')
server.register_function(subtract, 'subtract')
server.register_function(multiply, 'multiply')
server.register_function(divide, 'divide')
server.register_function(get_power, 'get_power')
server.serve_forever() 

客户端代码(复合调用):

import xmlrpclib

s = xmlrpclib.ServerProxy("http://192.168.137.9:8081/")
multicall = xmlrpclib.MultiCall(s)
multicall.add(7,3)
multicall.subtract(7,3)
multicall.multiply(7,3)
multicall.divide(7,3)
multicall.get_power(7,3)
result = multicall()

print "7+3=%d, 7-3=%d, 7*3=%d, 7/3=%d 7**3=%d" % tuple(result)

服务端代码(复合调用):

# python mul_xmlserver.py 
start service on 0.0.0.0 8081...

192.168.137.9 - - [22/May/2017 10:51:59] "POST / HTTP/1.1" 200 -

客户端代码(复合调用结果):

# python mul_xmlclient.py 
7+3=10, 7-3=4, 7*3=21, 7/3=2 7**3=343

此外,xmlrpc还提供了一些快捷函数:

1. xmlrpclib.boolean(value):将任意Python值转换为XML-RPC的布尔类型(True/False)。

2. xmlrpclib.dumps(params[, methodname[, methodresponse[, encoding[, allow_none]]]])

将params参数转换为XML格式。

3. xmlrpclib.loads(data[, use_datetime])

将XML-RPC请求数据转换回Python对象。

具体示例如下:

from xmlrpclib import ServerProxy, Error

server = ServerProxy("http://betty.userland.com")

print server

try:
 print server.examples.getStateName(41)
except Error as err:
 print "ERROR", err

客户端代码(快捷函数示例):

import xmlrpclib, httplib

class ProxiedTransport(xmlrpclib.Transport):
 def set_proxy(self, s):
  self.s = s

 def make_connection(self, host):
  self.realhost = host
  h = httplib.HTTPConnection(self.s)
  return h

 def send_request(self, connection, handler, request_body):
  connection.putrequest("POST", 'http://%s%s' % (self.realhost, handler))

 def send_host(self, connection, host):
  connection.putheader('Host', self.realhost)

p = ProxiedTransport()
p.set_proxy('proxy-server:8080')
server = xmlrpclib.ServerProxy('http://time.xmlrpc.com/RPC2', transport=p)
print server.currentTime.getCurrentTime()

以上关于Python远程调用RPC模块xmlrpclib的方法介绍完毕,希望能对读者有所帮助,欢迎参考与支持。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表