本文讲一下怎样用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. LN : leetcode 338 Counting Bits

    lc 338 Counting Bits 338 Counting Bits Given a non negative integer number num. For every numbers i ...

  2. cocos2d-x android 环境部署

    1.下载jdk http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 2.下载 and ...

  3. 盒子模型,top和margin-top

    1. 标准盒子模型: width只是内容的宽度. 元素的总宽度=width + padding*2 +border*2 +margin*2. IE盒子模型: width=内容的宽度 + padding ...

  4. Android 仿 新闻阅读器 菜单弹出效果(附源码DEMO)

    这一系列博文都是:(android高仿系列)今日头条 --新闻阅读器 (一) 开发中碰到问题之后实现的,觉得可能有的开发者用的到或则希望独立成一个小功能DEMO,所以就放出来这么一个DEMO. 原本觉 ...

  5. [算法天天练] - C语言实现双向链表(一)

    双向链表是比较常见的,主要是在链表的基础上添加prev指针,闲话少说直接上代码吧(这个也是网上一个大神的思路,真心不错,条理清楚,逻辑缜密) 主要也是为了学习,贴上我所调试成功的代码(Linux环境下 ...

  6. 【译】x86程序员手册27-7.6任务链

    7.6 Task Linking 任务链 The back-link field of the TSS and the NT (nested task) bit of the flag word to ...

  7. iOS UI布局总结

    布局就是尺寸和位置的设置. 一.基本布局: 1)绝对布局:frame.layoutsubviews. 二.相对布局: autoresizing.autolayout.基于父视图.基于约束. 三.线性布 ...

  8. PhpStorm 本地管理提交码云和GitHub代码仓库

    参考地址:https://www.yflad.cn/1766.html 1:下载Git客户端 2:打开PhpStorm,设置,Version Control → Git.配置git执行文件的路径.gi ...

  9. 01JavaScript使用

    JavaScript使用 1.内容写入 HTML <P onmouseover="alert('欢迎您学习JavaScript!')">鼠标移过来</P> ...

  10. 【转】Go语言入门教程(一)Linux下安装Go

    说明 系统是Ubuntu. 关于安装 下载安装包 当前官方下载地址是https://golang.org/dl/,如果不能访问,请自行FQ,FQ是技术工作者的必备技能. 安装 tar -xzvf go ...