2014-09-28 191 views
0

我想开始使用Delphi通过Onvif SOAP协议访问和控制IP摄像机。Delphi Onvif SOAP调用

但是,我不明白如何实际执行德尔福的调用。 我已经导入以下WDSL:

http://www.onvif.org/ver20/ptz/wsdl/ptz.wsdl

和在Delphi生成的单元。但是,如何执行对相机的呼叫?我应该使用这个与THTTPRIO一起生成吗?如何指定我拥有的相机的IP地址(目前是Axis Q1755相机)。

如果有人能通过指引我正确的方向让我开始,我将非常感激。

+0

要指定P地址:请参阅http://stackoverflow.com/questions/3596868/onvif-how-to-form-the-device-web-service-address-from-the-ip-address- of-an-nvt – mjn 2014-09-29 06:46:04

回答

1

如果你使用Delphi的WSDL进口商将已生成必要的类来表示任何request来回SOAP Web服务及其相应response

它也会生成一个wrapper,这将用于实际执行呼叫。通常它会有一些方法,如下列:

function mySoapMethod(myRequest: TmyRequestType): TMyResponse; 

要做到一个电话,你基本上做到以下几点:

  1. 得到一个wrapper实例引用。应在单位中有一种方法,称为类似于GetWrapper的东西。
  2. 如有必要,您将为request type创建实例并设置其所有属性。请注意,如果SOAP方法只需要几个基本类型作为参数,则可能没有请求类。还要考虑到任何足够复杂的request type可能意味着您将需要创建对象的实例并将它们作为属性分配给请求。
  3. 使用相应的wrapper method发送请求(或者如果它是简单调用,则设置参数)。
  4. 接收response对象并根据需要对其执行操作。

伪代码将是如下:

myWrapper := GetMyWrapper(); 
myRequest := TMyRequest.Create; 
//set myRequest properties 
myResponse := myWrapper.mySoapMethod(myRequest); 
//do whatever you need with the response 

关于包装

wrapper将是IInvokable接口增加了一些方法的实现。其实它应该有一个方法可以调用每个SOAP method

通常它的接口声明将是这样的:

TmyWrapper = interface(IInvokable) 
['...'] //GUID here 
    function oneMethod(...): oneMethodResponse; 
    function anotherMethod(...): anotherMethodResponse; 
end; 

function getMyWrapper(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): TmyWrapper ; 

而且功能的实现将是这样的:

function GetMyWrapper(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): TmyWrapper; 
const 
    defWSDL = 'http://<soap service IP and port>/<soap service name>?wsdl'; 
    defURL = 'http://<soap service IP and port>/<soap service name>'; 
    defSvc = '<default service name>'; 
    defPrt = '<default service port>'; 
var 
    RIO: THTTPRIO; 
begin 
    Result := nil; 
    if (Addr = '') then 
    begin 
    if UseWSDL then 
     Addr := defWSDL 
    else 
     Addr := defURL; 
    end; 
    if HTTPRIO = nil then 
    RIO := THTTPRIO.Create(nil) 
    else 
    RIO := HTTPRIO; 
    try 
    Result := (RIO as TmyWrapper); 
    if UseWSDL then 
    begin 
     RIO.WSDLLocation := Addr; 
     RIO.Service := defSvc; 
     RIO.Port := defPrt; 
    end else 
     RIO.URL := Addr; 
    finally 
    if (Result = nil) and (HTTPRIO = nil) then 
     RIO.Free; 
    end; 
end; 

一些旁注:

  • 您可以注入当您通过使用getXYZWrapper方法获取其实例时,将实例添加到wrapper。这可以帮助您例如设置另一个SOAP URL或检查生成的XML
  • 有时德尔福生成的XML将以与SOAP预期的稍有不同的方式发送。如果你认为它应该工作,但没有,请检查生成的XML,并将其与应该进行比较。您可以使用HTTPRIO对象的onBeforeExecute事件在发送之前修改XML
  • 我需要它,您也可以使用HTTPRIO对象的onAfterExecute方法来检查XML响应。
+0

感谢您的详细回复。不幸的是,我在生成的单元中没有Wrapper函数,看起来像你所建议的。我有一堆TRemotable类和一些枚举和接口。但是,如何将这些与HTTPRIO对象连接以调用我的相机? – TomRay74 2014-09-29 05:39:15

+0

@ TomRay74,对不起,昨天晚了,我写了这个答案。我会更新它以提供有关包装的更多详细信息。 – 2014-09-29 06:26:15