用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">
以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通信的更多相关文章
- [并发并行]_[线程模型]_[Pthread线程使用模型之三 客户端/服务端模型(Client/Server]
Pthread线程使用模型之三 客户端/服务端模型(Client/Server) 场景 1.在客户端/服务端模型时,客户端向服务端请求一些数据集的操作. 服务端执行执行操作独立的(多进程或跨网络)– ...
- 多个client与一个server端通信的问题
多个client与一个server端通信的问题 上篇博文主要是讲的关于client与server端的通信问题.在上篇博文中当我们仅仅有一个client訪问我们的server时是能够正常执行的,可是当我 ...
- java的服务端与客户端通信(1)
一.理解socket 1.1什么是socket? socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络 ...
- Socket编程--基础(基本server/client实现)
IPv4套接口地址结构 IPv4套接口地址结构通常也称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件中 LINUX结构下的常用结构,一般创建套接字的时候都要将这个结构里面的 ...
- 基于I/O的Server/Client实现
在前面的文章中讲了基于NIO实现的Server/Client.本文就讲讲基于同步堵塞式I/O实现的Server/Client好与前面的NIO中的Server/Client进行对照. 网络编程中须要解决 ...
- NetMQ(ZeroMQ)Client => Server => Client 模式的实现
ØMQ (也拼写作ZeroMQ,0MQ或ZMQ)是一个为可伸缩的分布式或并发应用程序设计的高性能异步消息库.它提供一个消息队列, 但是与面向消息的中间件不同,ZeroMQ的运行不需要专门的消息代理(m ...
- 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. ...
- grpc(3):使用 golang 开发 grpc 服务端和client
1,关于grpc-go golang 能够能够做grpc的服务端和client. 官网的文档: http://www.grpc.io/docs/quickstart/go.html https://g ...
- Consul集群Server+Client模式
Consul集群Server+Client模式 架构示意图 只使用Consul的Server模式有以下2个问题: 因为Consul Server数量受到控制所以压力承载(扩展性)是个问题. Serve ...
随机推荐
- CF540C Ice Cave
思路: 搜索. 加回溯会超时,不加回溯就过了,不是很理解. 实现: #include <iostream> #include <cstdio> using namespace ...
- 动态排序JavaBean
Java中如果对对象排序可以考虑实现Comparable接口,但是需要排序的属性一旦指定就不能再修改.BeanUtils组件提供了对JavaBean动态排序的支持,即可以在运行时指定排序的属性.实例运 ...
- git reset作用
git reset: 1. 文件从暂存区回退到工作区,撤销add 2. 版本回退 一:文件从暂存区回退到工作区,撤销add 如果想取消某个add的文件,可以使用该命令来进行撤销操作 撤消add:gi ...
- oracle in表达式参数支持最大上限1000个
oracle in表达式参数支持最大上限1000个 方法是拆分为多个 col in ... or col in ... #region 解决大于1000的问题 private String getSu ...
- Angular——自定义过滤器
基本介绍 除了使用AngularJS内建过滤器外,还可以根业务需要自定义过滤器,通过模块对象实例提供的filter方法自定义过滤器. 基本使用 (1)input是将绑定的数据以参数的形式传入 (2)i ...
- Java中PrintStream(打印输出流)
Java中PrintStream(打印输出流) PrintStream 是打印输出流,它继承于FilterOutputStream. PrintStream 是用来装饰其它输出流.它能为其他输出流 ...
- python学习笔记- 补遗
1.extend 和 append区别 extend 和 append区别 #extend接受list参数,添加每个元素至原list尾端 >>> l=[1,2,3] >> ...
- swift Hashable Equatable
/// You can use any type that conforms to the `Hashable` protocol in a set or /// as a dictionary ke ...
- 通过acdbblockreference 获得块名
AcDbBlockReference *pBlkRef = AcDbBlockReference::cast(ent.object()); AcDbObjectId pBlkTblRecId; ...
- Android table布局开发的一个简单的计算器
结果如图: XML文件如下: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" ...