PullMessages() 总是 return "InvalidArgVal"

PullMessages() always return "InvalidArgVal"

首先,我创建了一个 PullPoint 订阅,然后是订阅,但是当我在响应中向 uri 发送 PullMessages() 命令时,我总是得到相同的响应。你能看出问题是什么吗?

我的 PullMessages() 请求 -

<SOAP-ENV:Header>
<wsse:Security SOAP-ENV:mustUnderstand="true"><wsse:UsernameToken>
<wsu:Id="Id"><wsse:Username>admin</wsse:Username>
<wsse:Password=Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">cCMdBA6WisDrtJItFsSEbiQnifc=</wsse:Password>
<wsse:Nonce>HYwnVsldpikr+h8zuGsT9QTw8ec=</wsse:Nonce>
<wsu:Created>2015-10-21T12:59:09Z</wsu:Created></wsse:UsernameToken></wsse:Security>
<wsa5:Action SOAP-ENV:mustUnderstand="true">http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesRequest</wsa5:Action></SOAP-ENV:Header>
<SOAP-ENV:Body><tev:PullMessages><tev:Timeout>PT00H00M05S</tev:Timeout>
<tev:MessageLimit>1</tev:MessageLimit></tev:PullMessages>
</SOAP-ENV:Body></SOAP-ENV:Envelope>

来自设备的响应 -

<s:Header>
<wsa:Action>http://www.w3.org/2005/08/addressing/soap/fault</wsa:Action></s:Header>
<s:Body><s:Fault><s:Code><s:Value>env:Sender</s:Value>
<s:Subcode><s:Value>ter:InvalidArgVal</s:Value></s:Subcode></s:Code>
<s:Reason><s:Text xml:lang="en">Argument Value Invalid</s:Text></s:Reason>
<s:Node>http://www.w3.org/2003/05/soap-envelope/node/ultimateReceiver</s:Node>
<s:Role>http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver</s:Role>
<s:Detail><wsrf-r:ResourceUnknownFault><wsrf-bf:Timestamp>2015-10-21T12:58:50.937248Z</wsrf-bf:Timestamp></wsrf-r:ResourceUnknownFault></s:Detail>
</s:Fault></s:Body></s:Envelope>

P.S。 - 如果您需要更多信息,请随时询问

问题是我没有填写 header 中的 'to' 属性。

我发现最好的方法是查看来自 "Onvif device manager" 的数据包 在 wireshark 中查看我的代码中是否有不匹配的内容。

问题可能是因为您的订阅期限已过期。

如何检查: 在 wireshark 中,看到很少有初始的第一个 PullMessage 请求成功返回或超时。 (您还可以通过在 PullMessage 响应对象中打印来检查响应)。 跟踪响应 PullMessage 时提供的终止时间参数。 稍后当您发送请求时,您可能会将其发送给过期的订阅管理器,因此相机会给您 "InvalidArg".

如何解决: 请记住,wsdl 文档中的 PullMessage 描述并没有说相机每次收到 PullMessage 时都必须更新订阅。 大多数 Axis Cameras 从不更新它。因为他们严格遵循 onvif 标准。 所以,你可以做的是你可以使用订阅通知 RENEW 方法。您可以保留一个小于 PullPointSubscription 持续时间的计时器。并且在此计时器到期时,您可以发送 BaseNotification 方法的 RENEW 请求。这将更新 PullPoint 订阅管理器的订阅期限。

在我的情况下,问题是由于请求 header 未完全填写引起的,这与 ArielY 的情况类似。

工作请求必须与此类似:

POST /onvif/services HTTP/1.1
Host: >IpAddress<
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 930

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://www.onvif.org/ver10/events/wsdl/PullPointSubscription/PullMessagesRequest</a:Action>
    <a:MessageID>urn:uuid:27577591-b1f2-4750-a705-5036364fefc9</a:MessageID>
    <Security>...</Security>
    <a:ReplyTo>
      <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <SubscriptionId a:IsReferenceParameter="true" xmlns="http://www.axis.com/2009/event" xmlns:dom0="http://www.axis.com/2009/event">41</SubscriptionId>
    <a:To s:mustUnderstand="1">http://>IpAddress</onvif/services</a:To>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <PullMessages xmlns="http://www.onvif.org/ver10/events/wsdl">
      <Timeout>PT20S</Timeout>
      <MessageLimit>2</MessageLimit>
    </PullMessages>
  </s:Body>
</s:Envelope>

似乎唯一可以省略的是ReplyTo标签。 起初我省略了 Action、MessageId、ReplyTo 和 SubscriptionId。

编辑:对于某些相机,必须仅存在 SubscriptionId。