我有一个设备定期向我在我的计算机上运行的 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 = ""
 }
但这几乎是我所能做的。
老实说,我仍然不知道我需要服务器还是客户端......