本文讲一下怎样用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">

以string为例(事实上tolist更简单),

Server:

from SimpleXMLRPCServer import SimpleXMLRPCServer
global a
import ast
from cStringIO import StringIO
from numpy.lib import format
import numpy class T:
def to_string(self,arr):
f = StringIO()
if type(arr)==numpy.ndarray:
format.write_array(f,arr)
s = f.getvalue()
elif isinstance(arr,str)==False:
s = str(arr)
return s def from_string(self,s):
if s[0]!="[": # converted from numpy array
f = StringIO(s)
arr = format.read_array(f)
else:
arr = ast.literal_eval(s)
return arr def load(self):
global a
a = [1 ,2, 24]
return a def ret_a(self):
global a
return a server = SimpleXMLRPCServer(("localhost", 8002))
server.register_instance(T())
srv = T()
srv.load()
server.serve_forever()

Client:

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8002/") candidate = proxy.ret_a()
print "the variable 'a' in server is "+ str((proxy.from_string(candidate)))

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')

for example,

Server:

from SimpleXMLRPCServer import SimpleXMLRPCServer
global a
import ast
from cStringIO import StringIO
from numpy.lib import format
import numpy
import sys def gbk_to_unicode(s):
return s.decode('gbk').encode('utf-8').decode('latin1') class T: def load(self): # load a dictionary with gbk elements
global a
a = {"1,1":["小","苹果"],"1,2":[1,2]} def printf(self,s): # receive unicode, return unicode
print "received string : "+ s #unicode
return s def idx(self,s): # transfer gbk -> unicode to client
global a
return [gbk_to_unicode(x) for x in a.get(s,[])] reload(sys)
sys.setdefaultencoding('gbk')
server = SimpleXMLRPCServer(("localhost", 8002))
server.register_instance(T())
srv = T()
srv.load()
server.serve_forever()

Client:

import xmlrpclib
proxy = xmlrpclib.ServerProxy("http://localhost:8002/") # method 1. 用unicode编码 s = u"美女"
print "the variable to transfer is "+ s
res_u1 = proxy.printf(s) # method 2. decode to unicode
s = "美女"
print "the variable to transfer is "+ s
res_u2 = proxy.printf(s.decode('latin1')) assert res_u1 == res_u2
res_gbk = res_u1.encode('latin1')
print res_gbk # 再进一步 def unicode_to_gbk(s):
return s.encode('latin1').decode('utf-8').encode('gbk') res = proxy.idx("1,1") # receive unicode
a = [unicode_to_gbk(s) for s in res] # transfer unicode->gbk
print a[0], a[1]

用XMLRPC开服务进行server/client通信的更多相关文章

  1. [并发并行]_[线程模型]_[Pthread线程使用模型之三 客户端/服务端模型(Client/Server]

    Pthread线程使用模型之三 客户端/服务端模型(Client/Server) 场景 1.在客户端/服务端模型时,客户端向服务端请求一些数据集的操作. 服务端执行执行操作独立的(多进程或跨网络)– ...

  2. 多个client与一个server端通信的问题

    多个client与一个server端通信的问题 上篇博文主要是讲的关于client与server端的通信问题.在上篇博文中当我们仅仅有一个client訪问我们的server时是能够正常执行的,可是当我 ...

  3. java的服务端与客户端通信(1)

    一.理解socket 1.1什么是socket? socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络 ...

  4. Socket编程--基础(基本server/client实现)

    IPv4套接口地址结构 IPv4套接口地址结构通常也称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件中 LINUX结构下的常用结构,一般创建套接字的时候都要将这个结构里面的 ...

  5. 基于I/O的Server/Client实现

    在前面的文章中讲了基于NIO实现的Server/Client.本文就讲讲基于同步堵塞式I/O实现的Server/Client好与前面的NIO中的Server/Client进行对照. 网络编程中须要解决 ...

  6. NetMQ(ZeroMQ)Client => Server => Client 模式的实现

    ØMQ (也拼写作ZeroMQ,0MQ或ZMQ)是一个为可伸缩的分布式或并发应用程序设计的高性能异步消息库.它提供一个消息队列, 但是与面向消息的中间件不同,ZeroMQ的运行不需要专门的消息代理(m ...

  7. docker报Error response from daemon: client is newer than server (client API version: 1.24, server API version: 1.19)

    docker version Client: Version: 17.05.0-ce API version: 1.24 (downgraded from 1.29) Go version: go1. ...

  8. grpc(3):使用 golang 开发 grpc 服务端和client

    1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://g ...

  9. Consul集群Server+Client模式

    Consul集群Server+Client模式 架构示意图 只使用Consul的Server模式有以下2个问题: 因为Consul Server数量受到控制所以压力承载(扩展性)是个问题. Serve ...

随机推荐

  1. Microsoft SQL Server学习(五)--操作符聚合函数

    算术运算符 逻辑运算符 比较运算符 聚合函数 算术运算符(+ - * / ) select score*2 as 成绩翻倍 from class_A update class_A set score= ...

  2. 携程transform放大效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. Android Measure 体系简单总结

    Android对View的测量是半协商半强制半模糊半具体的. 测量过程中的两套尺寸体系:  [半强制] ParentView**约束ChildView: **MeasureSpec(通过measure ...

  4. 类似倒圆角方法输入半径选择实体 kword

    ads_name ename; ads_point adspt; acedInitGet(NULL, TEXT("R")); while (1) { int rc = acedEn ...

  5. java_IO_装饰器

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

  6. 浅谈FFC

    FFC(Flexible Formatting Context) CSS3引入了一种新的布局模型——flex布局(之前有文章介绍过).flex是flexible box的缩写,一般称之为弹性盒模型.和 ...

  7. CodeFrist基础_Fluent Api

    一丶首先新建两个实体类 public class Student { public int StudentKey { get; set; } public string StudentName { g ...

  8. POJ2152 Fire (树形DP)

    题意:n个城市n-1条边 组成一棵树 在每个城市修建消防站会有一个花费costi 每个城市能防火当且仅当地图上距离他最近的消防站距离小于di   问如何修建消防站 使地图上所有的城市都有预防火灾的能力 ...

  9. Python Web开发

    参考原文 Python廖雪峰 WSGI接口 WSGI(Web Server Gateway Interface)是一个接口,用来屏蔽底部的细节(如TCP的建立连接,HTTP原始请求和响应格式等).WS ...

  10. spring源码下载链接

    http://www.blogjava.net/zhyiwww/archive/2014/10/17/418809.html