我有一个设备定期向我在我的计算机上运行的 HTTP 服务器发送 SOAP 通知。通知如下所示:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<Notify>
<DeviceNotification message= "
<NotificationEvent NotificationType="Location">
<ComputerLocation changedOn="1369757031051">
</ComputerLocation>
</NotificationEvent>
"/>
</Notify>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
它是一个 SOAP 信封,其中包含 DeviceNotification 类型实例的 XML 表示。
我真的不知道如何处理这些通知(好像我的程序是服务器?客户端?)。通知看起来更像是对命令的响应,但我实际上并没有调用任何远程服务(发送通知的机器有一个 Web 界面,我在其中输入“通知的目的地:此 ip,此端口”并开始发送他们)我也不确定通知中的 SOAP 是否完全正确。
我已经尝试了几个 SOAP 库等等......我认为我能够实现的最接近的事情是使用spyne(或者可能只是海市蜃楼,我认为这是因为它比其他库输出更多的东西)
class DeviceNotification(ComplexModel):
___namespace__ = ""
pass
class HelloWorldService(ServiceBase):
@rpc(DeviceNotification, _returns=Iterable(Unicode))
def Notify(message):
logging.warn("CHECKPOINT")
print "message: %s" % message
return ["foobarbaz"]
if __name__=='__main__':
from wsgiref.simple_server import make_server
PORT=7171
application = Application([HelloWorldService],
tns="",
in_protocol=HttpRpc(validator='soft'),
out_protocol=JsonDocument()
)
wsgi_application = WsgiApplication(application)
server = make_server('', PORT, wsgi_application)
server.serve_forever()
但是Notify函数永远不会被调用。我得到:
192.168.1.33 - - [28/May/2013 21:16:52] "POST / HTTP/1.1" 404 130
DEBUG:spyne.server.wsgi:Method name: '{}'
DEBUG:spyne.protocol.http: header : {'soapaction': ['Notify'], 'host': ['niuyorker.jome:7171'], 'user_agent': ['Jakarta Commons-HttpClient/3.1']
这是我得到的最接近的东西。那个 SOAP 消息正确吗?如果是,以及这应该被视为对服务器(我的服务器)的请求还是作为响应(因此,我的应用程序将是一个客户端)。如果有人知道在哪里可以找到 Python 和 SOAP 的示例比添加两个数字或多次说“你好”更复杂一点,这也会有所帮助?
我想我总是可以使用lxml来解析整个 SOAP 消息,但如果可能的话,我想更“专业”地做一点。以防万一您没有注意到:我完全是 SOAP 服务的新手!:)
先感谢您!
更新:
看起来消息部分实际上应该是转义的 XML,它......嗯......这是我从一开始就得到的,但是(我是新手)我把它转义了,所以它在问题中看起来更漂亮。真实的是:
<soap-env:envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:body>
<notify>
<notification message='<NotificationEvent NotificationType="Location"><DeviceLocation changedOn="1369074622065"></DeviceLocation></NotificationEvent>'>
</notification>
</notify>
</soap-env:body>
</soap-env:envelope>
我确实有 WSDL。使用suds我已经能够创建“ComputerLocation”类型的实例,例如:
>>> from suds.client import Client
>>> url="file:///tmp/service.wsdl"
>>> c=Client(url)
>>> c.factory.create('DeviceLocation')
(DeviceLocation){
_changedOn = ""
}
但这几乎是我所能做的。
老实说,我仍然不知道我需要服务器还是客户端......