全部博文(68)
分类: LINUX
2011-11-01 14:48:13
Python同样也提供了一个基于XMLRPC的解决方案,不过用法很简单:
首先,就好像在编写普通的程序那样子编写服务器。
接着使用SimpleXMLRPCServer模块运行XMLRPC服务器,在其中注册服务器提供的函数或者对象。
最后,在客户端内使用xmlrpclib.ServerProxy连接到服务器,想要调用服务器的函数,直接调用ServerProxy即可。
一个最简单的hello,word示例:
#helloserver.py
from SimpleXMLRPCServer import SimpleXMLRPCServer
def hello():
print "hello,world!"
svr=SimpleXMLRPCServer(("", 8080), allow_none=True)
svr.register_function(hello)
svr.serve_forever()
#helloclient.py
from xmlrpclib import ServerProxy
svr=ServerProxy("")
svr.hello()
先后运行helloserver.py和 helloclient.py就可以看到控制台输出hello,world
不过,美中不足的 是,SimpleXMLRPCServer是一个单线程的服务器。这意味着,如果几个客户端同时发出多个请求,其它的请求就必须等待第一个请求完成以后才 能继续。这里有个技巧解决这个问题:
from SocketServer import
ThreadingMixIn
class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):pass
现在把helloserver改一改:
svr=ThreadXMLRPCServer(("", 8080), allow_none=True)
现在服务器就支持多线程并发了。
XMLRPC一个标准协议,定义了如何使用HTTP和 XML来传递多种类型数据。据我观察,xmlrpclib对于日期/时间类型的有特殊的支持。假如有一个服务器提供的函数是:
def toluar(d):pass
这原本是一个将阳历转换成阴历的函数。要求d是 datetime模块里的datetime类型。虽然客户端确实传入的确实是datetime类型,服务器却会将其解释为 xmlrpclib.DateTime类型。 解决办法是:
class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):
#从SimpleXMLRPCServer模块抄出来的代码
def _marshaled_dispatch(self, data, dispatch_method = None):
try:
params, method = xmlrpclib.loads(data,
use_datetime=True) #这里加了一个use_datetime
# generate response
if dispatch_method is not None:
response = dispatch_method(method, params)
else:
response = self._dispatch(method, params)
# wrap response in a singleton tuple
response = (response,)
response = xmlrpclib.dumps(response,
methodresponse=1,
allow_none=self.allow_none,
encoding=self.encoding)
except Fault, fault:
response = xmlrpclib.dumps(fault, allow_none=self.allow_none,
encoding=self.encoding)
except:
# report exception back to server
exc_type, exc_value, exc_tb = sys.exc_info()
response = xmlrpclib.dumps(xmlrpclib.Fault(1, "%s:%s" % (exc_type, exc_value)),encoding=self.encoding, allow_none=self.allow_none,)
return response
svr=ThreadXMLRPCServer(("", 8080), allow_none=True)
客户端方面则比较简单:
svr=ServerProxy("/", allow_none=True, use_datetime=True)
注意 use_datetime参 数默认是False