赵斌

赵斌的博客

他的个人主页  他的博客

Python 多线程XML-RPC的实现

赵斌  2009年08月15日 星期六 01:13 | 3724次浏览 | 0条评论

原文通过blogbus2zeuux工具同步发布:http://antmanler.blogbus.com/logs/43841379.html

文章发布时间:2009/4/10/3/21

Python 多线程XML-RPC的实现
一、 引言
用Python的SimpleXMLRPCServer实现的XML-RPC服务器只能是单线程,一个一个的处理请求,对于操作中耗时较长的操作会阻塞其他用户请求,使服务质量下降,因此有没有办法让SimpleXMLRPCServer成为多线程服务器呢?
主要有两种实现方法:修改SimpleXMLRPCServer的实现代码,用ThreadingMixIn或 ForkingMixIn。
 
二、 修改SimpleXMLRPCServer的实现代码
SimpleXMLRPCServer的实现如下:
class SimpleXMLRPCServer(SocketServer.TCPServer,
                         SimpleXMLRPCDispatcher):
如果我们将其继承的SocketServer.TCPServer,改为支持线程处理的ThreadingTCPServer,即可将SimpleXMLRPCServer变成多线程的服务器,如下:
class SimpleXMLRPCServer(SocketServer.ThreadingTCPServer,
                         SimpleXMLRPCDispatcher):
 
三、 用ThreadingMixIn实现
SocketServer模块中就支持对线程(Threading)或进程(Fork)的支持,典型代码如下:

import   SimpleXMLRPCServer , SocketServer
import win32api , thread
#The server object
class Server :
    count = 0
    def __init__ ( self ):
        pass
    def echoString ( self , strs ):
        mutex . acquire () #用mutex锁住数据
        Server . count += 1 #更改静态数据
        t = time . strftime ( "Serve at %I:%M:%S Id is " ) + str ( Server . count )
        print "Serve Id " + str ( Server . count )
        mutex . release () #释放锁
        #win32api.Sleep(20000)
        return t
#多线程实现
class RPCThreading ( SocketServer . ThreadingMixIn , SimpleXMLRPCServer . SimpleXMLRPCServer ):
    pass
global mutex
mutex = thread . allocate_lock ()
server_object = Server ()
server = RPCThreading (( "localhost" , 8888 ))
server . register_instance ( server_object )
#Go into the main listener loop
print "Listening on 8888"
server . serve_forever ()

通过上面的代码也可以实现XML-RPC的多线程支持而不用修改Python的
SimpleXMLRPCServer库。

转:下面顺便转个压缩发送的:

compression. (Disclaimer : I'm not a python expert in any way, just sharing...)

xmlrpc is great, easy, dynamic but is not effecient as binary methods (see "The Python Web services developer: Messaging technologies compared" at http://www.ibm.com/developerworks/library/ws-pyth9/).

For example, it can take minutes to transfer 100MB of data between client and server.

Therefore, I added compression, using http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/355486.

This shortened the transfer time to 15 seconds. Example server function (returns an arbitrary chunk of bytes, possibly with random values):

from array import array
from random import randint
import zlib , base64

def get_data ( self , default_byte_value = 0x00 , num_bytes = 1024 , use_rand = False ):
    data = array ( 'B' , [ default_byte_value ] * num_bytes )
    if ( use_rand ):
        for i in range ( num_bytes ):
        data [ i ] = randint ( 0 , 255 )
        data , csum = asciiCompress ( buffer ( data ))
        return data

Example client side (request a 1MB chunk of bytes using 0x11 as default value for each byte (non random)).

data = server . get_data ( 0x11 , 1 * 10 ** 6 , False )
data , csum = asciiDecompress ( data )
arr = array ( 'B' , data )

Note that we originate from a python array at the server and end up with an array at the client.

Just my 2 cents :)

评论

我的评论:

发表评论

请 登录 后发表评论。还没有在Zeuux哲思注册吗?现在 注册 !

暂时没有评论

Zeuux © 2024

京ICP备05028076号