本文讲一下怎样用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. BZOJ1499: [NOI2005]瑰丽华尔兹(dp)

    Description 你跳过华尔兹吗?当音乐响起,当你随着旋律滑动舞步,是不是有一种漫步仙境的惬意?众所周知,跳华尔兹时,最重要的是有好的音乐.但是很少有几个人知道,世界上最伟大的钢琴家一生都漂泊在 ...

  2. Asp.net MVC中文件上传的参数转对象的方法

    参照博友的.NET WebApi上传文件接口(带其他参数)实现文件上传并带参数,当需要多个参数时,不想每次都通过HttpContext.Request.Params去取值,就针对HttpRequest ...

  3. opencv3.3+vs2015调用笔记本摄像头成功

    先上代码 成功图片如下: #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp&g ...

  4. Codewars练习Python

    计算一个数组的中间数,数的两边和相等,并返回index值 如:数组[1,2,3,4,6] 返回3(数组序号从0开始) def find_even_index(arr): ""&qu ...

  5. (转) 淘淘商城系列——redis-desktop-manager的使用

    http://blog.csdn.net/yerenyuan_pku/article/details/72849791 实际工作环境中,redis会安装在服务器上,我们想使用redis服务就要使用re ...

  6. codeforces_459D_(线段树,离散化,求逆序数)

    链接:http://codeforces.com/problemset/problem/459/D D. Pashmak and Parmida's problem time limit per te ...

  7. JVM 参数含义

    JVM参数的含义 实例见实例分析 参数名称 含义 默认值   -Xms 初始堆大小 物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,J ...

  8. Vue-prop

    HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符.这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab- ...

  9. ThinkPHP---TP功能类之公文管理功能2----------继续完善

    [前言] 之前已经完成了公文的添加和列表展示功能,今天继续完善.做下公文的编辑和删除功能. [主体] (1)分析 控制器:DocController.class.php 方法:edit(将模板展示和数 ...

  10. 08Webpage Form

    Webpage Form 表单(form)在网页中主要负责数据采集功能.一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法. 表单域:包含 ...