Python challenge 14 - xmlrpclib & RPC protocol

第十四题地址:http://www.pythonchallenge.com/pc/return/disproportional.html



题目中的图片,点击数字5跳转到新地址: http://www.pythonchallenge.com/pc/phonebook.php。得到一个XML文档。

<methodResponse>
    <fault>
        <value>
            <struct>    
                <member>
                    <name>faultCode</name>
                    <value>
                        <int>105</int>
                    </value>
                </member>
                <member>
                    <name>faultString</name>
                    <value>
                        <string>
                            XML error: Invalid document end at line 1, column 1
                        </string>
                    </value>
                </member>
            </struct>
        </value>
    </fault>
</methodResponse>


然后我们在图片下面还知道要我们做的是phone that evil。Evil是什么呢,在之前的那题中,我们知道evil就是Bert。(网上都说用IE浏览器可以看到,但是我还是只能在命令行返回值中得到这个结果。)



对于一个XML文档,我们怎么进行操作呢。搜索得到的理由是因为这题用到了RPC - Remote Procedure Call的协议,然后python标准库中有xmlrpclib这个模块。在python 3x中被更名为xmlrpc.client。



那么接下来,我们就导入xmlrpclib然后对XML进行操作。


import xmlrpclib
connect = xmlrpclib.ServerProxy("http://www.pythonchallenge.com/pc/phonebook.php")


print connect.system.listMethods()
# ['phone', 'system.listMethods', 'system.methodHelp', 'system.methodSignature', 'system.multicall', 'system.getCapabilities']


print connect.system.methodHelp("phone")
# Returns the phone of a person


print connect.phone("Bert")
# 555-ITALY

上述的方法会在接下来详细讲述。最后得到的结果是 555-ITALY。但是关键词只需要ITALY,但是提示是SMALL letters, 所以是italy。



####################################################################################################################################


RPC protocol


Remote Procedure Call Protocol - 远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,比如TCP或者UDP,为通信过程之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。


工作原理:

1. 调用客户端句柄;执行传送参数

2. 调用本地系统内核发送网络消息

3. 消息传送到远程主机

4. 服务器句柄得到消息并取得参数

5. 执行远程过程

6. 执行的过程将结果返回服务器句柄

7. 服务器句柄返回结果,调用远程系统内核

8. 消息传回本地主机

9. 客户句柄由内核接收消息

10. 客户接收句柄返回的数据



python xmlrpclib 模块

XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport. With it, a client can call methods with parameters on a remote server (the server is named by a URI) and get back structured data. This module supports writing XML-RPC client code; it handles all the details of translating between conformable Python objects and XML on the wire.

XML-RPC 是 Remote Procedure Call 方法,使用XML通过HTTP传输。使用XML-RPC,一个客户端可以在远程的服务器上(服务器使用URI命名)用参数调用方法,并得到结构化的数据返回值。Python xmlrpclib模块支持XML-RPC客户端代码,支持所有的Python对象和XML之间的转换。



比较关键的ServerProxy对象

ServerProxy.system.listMethods()

返回一个list,里面存着的都是String,都是支持XML-RPC server 的方法。


ServerProxy.system.methodSignature(name)

传入一个方法名作为参数,返回方法可能的signatures。一个signature就是一个types类型的数组集合。第一个类型就是方法返回值的类型,其他的是参数的类型。因为多种signatures是被允许的(overloading),所以这个方法返回一串signatures,而不是单一singleton。

Signatures,比如一个方法需要一个array作为参数,返回一个string。那么方法返回的是“string,array”。如果是需要3个integers作为参数,返回一个string,那么方法的返回值是“string,int,int,int”。

如果方法没有定义signature,那么返回non-array。Python中,这意味着返回值回是任何,但是不是list。


ServerProxy.system.methodHelp(name)

传入一个方法名作为参数,返回方法的具体使用描述。如果没有描述,那么就返回一个空的string。这个string描述文档可以包含HTML的修饰。



其他还有Boolean,DateTime, Binary, Fault, ProtocolError, MultiCall等对象,具体的描述请看参考中的Python文档链接。



一个调用了xmlrpclib模块的简单Hello World示例:

#helloserver.py
from SimpleXMLRPCServer import SimpleXMLRPCServer

def hello():
    print "hello,world!"

svr=SimpleXMLRPCServer(("", 8080), allow_none=True)
svr.register_function(hello)
svr.serve_forever()


#helloclient.py
from xmlrpclib import ServerProxy
svr=ServerProxy("http://localhost:8080")
svr.hello()

对于上述的代码,我们先运行helloserver.py,然后运行helloclient.py,可以再控制台输出hello,world!


127.0.0.1 - - [29/Nov/2014 23:21:43] "POST /RPC2 HTTP/1.1" 200 -
hello,world!


P.S. 处理并发

SimpleXMLRPCServer是一个单线程的服务器。意味着如果几个客户端同事发出多个请求,那么并需等待第一个请求完成之后才能继续,下面技巧解决此类问题:

from SimpleXMLRPCServer import SimpleXMLRPCServer
from SocketServer import ThreadingMixIn
class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):
    pass

把helloserver.py改一改:

svr=ThreadXMLRPCServer(("", 8080), allow_none=True)

然后服务器就支持多线程并发了。




参考:

http://en.wikipedia.org/wiki/Remote_procedure_call

http://baike.baidu.com/view/7287257.htm?fromtitle=RPC%E5%8D%8F%E8%AE%AE&fromid=5019569&type=syn

https://docs.python.org/2/library/xmlrpclib.html

http://hgoldfish.com/blogs/article/50/

http://my.oschina.net/sanpeterguo/blog/100593

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值