首页 > 代码库 > 用XMLRPC开服务进行server/client通信

用XMLRPC开服务进行server/client通信

本文讲一下如何用python的xmlrpc开服务,进行server/client的通信。

应用场景:1)需多client访问应用程序给予应答情况——网页服务;  2)数据极大,希望加载一次,后面只用方法调用

解决方案:  开两个服务,一个数据服务,一个网络服务;
 数据服务端加载数据,网络服务端调用数据,并将结果显示在网络服务中;
 外部调用网络服务返回结果;

应用工具:xmlrpc,本文中以python 2.7.3的xmlrpclib为例,其他语言也有相应接口

下面分别说明。


1. 数据端

在本地localhost的8000端口开server服务,load数据,并定义接口查找数据第i个元素(findai).

Server :

from SimpleXMLRPCServer import SimpleXMLRPCServer
global a

def load():
	global a
	a = [1 ,2, 24]
	return a

def findai(i):
	global a
	print a[i]
	return a[i]

server = SimpleXMLRPCServer(("localhost", 8000))
server.register_function(findai,"findai")
load()
server.serve_forever() 


Client:

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8000/")

candidate = proxy.findai(1)
print "the %d-th number of a is %d" %(1, candidate)




2. 数据端 + 网络端

Client:

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8000/")

candidate = proxy.findai(1)
print "the %d-th number of a is %d" %(1, candidate)

from bottle import route, run, template
@route(‘/hello/<name>‘)
def index(name):
	return template(‘<b> hello {{name}} </b>‘, name=candidate)

run(host="localhost", port=8086)


注意事项:

1. 通信数据类型

注意通讯数据类型只能是python的built-in类型(而不能是numpy类型),所以其他类型应转换为str类型(client端用ast.literal_eval从str转回来)或者更方便的用list(直接server端tolist转,client端numpy.array解);

否则会报错:

xmlrpclib.Fault:  <Fault  8002:  "Can‘t serialize output: cannot marshal <type ‘numpy.float64‘> objects">


2. 通讯字符编码问题

注意通讯字符必须是unicode编码,用中文的时候要小心。

所以中文的case下,在server段执行:

def gbk_to_unicode(s):
    return s.decode(‘gbk‘).encode(‘utf-8‘).decode(‘latin1‘)


client端执行:

def unicode_to_gbk(s):
    return s.encode(‘latin1‘).decode(‘utf-8‘).encode(‘gbk‘)