コンピューターで実行している 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>
これは、タイプ DeviceNotification のインスタンスの XML 表現を含む SOAP エンベロープです。
これらの通知をどのように処理するかはよくわかりません (私のプログラムがサーバーかクライアントかのように)。通知はコマンドへの応答のように見えますが、実際にはリモート サービスを呼び出しているわけではありません (通知を送信するマシンには、「通知の宛先: この ip、このポート」を入力する Web インターフェイスがあり、送信を開始しますそれら) 通知の 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 を使用して、2 つの数字を追加したり、「こんにちは」と何度も言ったりするよりも少し複雑な例を見つけられる場所を誰かが知っていれば、それも役に立ちますか?
いつでも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 = ""
}
しかし、それは私ができることのほとんどすべてです。
正直なところ、サーバーが必要かクライアントが必要かはまだわかりません...