用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 ...
随机推荐
- jboss 配置虚拟路径
1.找到jboss服务器下server.xml文件.我用的是web用户,所以在web用户下找 路径:G:\skWorkspace\Jboss\server\web\deploy\jbossweb.sa ...
- jQuery 遍历 - children() 方法
jQuery 遍历参考手册 实例 找到类名为 "selected" 的所有 div 的子元素,并将其设置为蓝色: $("div").children(" ...
- day15-模块的基础及导入
目录 模块 什么是模块 使用模块 import 循环导入问题 解决方案一 解决方案二 模块的搜索路径 Python文件的两种用途 包 导入包内包 导入包内包的模块 绝对导入与相对导入 绝对导入 相对导 ...
- JAVA基础——IO流字节流
在Java中把不同的输入输出源(键盘.文件.网路连接)抽象表述为“流”. 1.输入流.输出流 .字节输入流通过FileInputStream和来操作 字节输出流通过FileOutputStream来操 ...
- Android 按钮常用点击事件大总结
很多学习Android程序设计的人都会发现每个人对代码的写法都有不同的偏好,比较明显的就是对控件响应事件的写法的不同.因此本文就把这些写法总结一下,比较下各种写法的优劣,希望对大家灵活地选择编码方式可 ...
- 1054.求平均数-PAT乙级真题
从其他博客优秀代码中学到了些技巧,记录一下. 思路:使用sscanf和sprintf函数. sscanf() – 从一个字符串中读进与指定格式相符的数据 sprintf() – 字符串格式化命令,主要 ...
- oracle 清理跟踪文件.trc .trm
trc,trm文件介绍:trc:系统的跟踪文件(trace),当系统启动时或运行过程中出现错误时,系统会自动记录跟踪文件到指定的目录,以便于检查,这些文件需定期维护删除.trm:伴随着.trc文件产生 ...
- 在线安全清空慢查询日志slowlog
mysql> show variables like '%slow_query%';+------------------------------------+--------------- ...
- 第十五节:Web爬虫之selenium动态渲染爬取
selenium是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firef ...
- 移动端禁止滑动的js处理方式
下面是禁止移动端滑动事件的方式,慎用 document.querySelector('body').addEventListener('touchmove', function (ev) { ...