![]() |
Delphi Client für C# WCF-Service mit wsDualHttp-Binding
Hallo Zusammen,
ich möchte in Delphi 2007 Methoden in einer WCF abrufen, welche in C#, also .net gehostet wird. Das funktioniert mit basicHttp-Binding auch. Da ich aber Callbacks implementieren muss kommt das nicht in Frage. Duplex-Bindings sind netTcp-Binding und wsDualHttp-Binding. netTcp-Binding kann auf Grund fehlender Interoperabilität nicht in Delphi verwendet werden. WsDualHttp-Binding ist laut MSDN interoperabel. Ich kann in Delphi die wsdl-Datei fehlerfrei kompilieren und das Programm startet dann auch. Wenn man aber den Befehl ausführt kommt die Meldung das an der Adresse ffffffff ein Fehler aufgetreten ist. Ich habe mal ein Demoprojekt erstellt um das ganze zu testen. Es soll eine Methode aufgerufen werden, welche zwei double als Parameter erhält. Diese Methode addiert beide Variablen und soll das Ergebnis über die Callbackmethode an den Delphi-Client senden. Die WCF bietet eine Methode an: void Add(double n, double m); Die Callback-Methode: void Result(double result); Was mir noch überhaupt nicht klar ist: Wie definiere ich die Callback-Methode? Der Callback-Contract ist mit IDuplexDemoCallback bezeichnet. Diese Bezeichnung findet man in der vom wsdl-Importer erstellten Unit nicht. Hier der aufrufende Quelltext:
Delphi-Quellcode:
und hier die Unit, die vom Delphi wsdl-Importer erstellt wurde:
var ws:IDuplexDemo;
param:Add; begin param.n := 2.2; param.m := 2.8; ws:=GetIDuplexDemo(false); ws.Add(param); end;
Delphi-Quellcode:
Ich bitte um Eure mithilfe!
// ************************************************************************ //
// Die in dieser Datei deklarierten Typen wurden aus Daten der unten // beschriebenen WSDL-Datei generiert: // WSDL : http://localhost:1235/DuplexDemo // >Import : http://localhost:1235/DuplexDemo>0 // >Import : http://localhost:1235/DuplexDemo?xsd=xsd0 // >Import : http://localhost:1235/DuplexDemo?xsd=xsd1 // Codierung : utf-8 // Version: 1.0 // (06.06.2012 20:09:31 - - $Rev: 45757 $) // ************************************************************************ // unit DuplexDemo; interface uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns; const IS_OPTN = $0001; IS_REF = $0080; type // ************************************************************************ // // Die folgenden Typen, auf die im WSDL-Dokument Bezug genommen wird, sind in dieser Datei // nicht repräsentiert. Sie sind entweder Aliase[@] anderer repräsentierter Typen oder auf sie wurde Bezug genommen, // aber sie sind in diesem Dokument nicht[!] deklariert. Die Typen aus letzterer Kategorie // sind in der Regel vordefinierten/bekannten XML- oder Embarcadero-Typen zugeordnet; sie könnten aber auf // ein inkorrektes WSDL-Dokument hinweisen, das einen Schematyp nicht deklariert oder importiert hat. // ************************************************************************ // // !:double - "http://www.w3.org/2001/XMLSchema"[Gbl] Add = class; { "http://tempuri.org/"[Lit][GblElm] } Result = class; { "http://tempuri.org/"[Lit][GblElm] } // ************************************************************************ // // XML : Add, global, <element> // Namespace : http://tempuri.org/ // Serializtn: [xoLiteralParam] // Info : Wrapper // ************************************************************************ // Add = class(TRemotable) private Fn: Double; Fn_Specified: boolean; Fm: Double; Fm_Specified: boolean; procedure Setn(Index: Integer; const ADouble: Double); function n_Specified(Index: Integer): boolean; procedure Setm(Index: Integer; const ADouble: Double); function m_Specified(Index: Integer): boolean; public constructor Create; override; published property n: Double Index (IS_OPTN) read Fn write Setn stored n_Specified; property m: Double Index (IS_OPTN) read Fm write Setm stored m_Specified; end; // ************************************************************************ // // XML : Result, global, <element> // Namespace : http://tempuri.org/ // Serializtn: [xoLiteralParam] // Info : Wrapper // ************************************************************************ // Result = class(TRemotable) private Fresult: Double; Fresult_Specified: boolean; procedure Setresult(Index: Integer; const ADouble: Double); function result_Specified(Index: Integer): boolean; public constructor Create; override; published property result: Double Index (IS_OPTN) read Fresult write Setresult stored result_Specified; end; // ************************************************************************ // // Namespace : http://tempuri.org/ // soapAction: http://tempuri.org/IDuplexDemo/%operationName% // Transport : http://schemas.xmlsoap.org/soap/http // Stil : document // Verwenden von : literal // Bindung : WSDualHttpBinding_IDuplexDemo // Service : CalculatorService // Port : WSDualHttpBinding_IDuplexDemo // URL : http://192.168.0.224:1234/DuplexDemo // ************************************************************************ // IDuplexDemo = interface(IInvokable) ['{DEDB3533-FA08-88C8-BB25-8388A7E5AA41}'] procedure Add(const parameters: Add); stdcall; function Result: Result; stdcall; end; function GetIDuplexDemo(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): IDuplexDemo; implementation uses SysUtils; function GetIDuplexDemo(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): IDuplexDemo; const defWSDL = 'http://localhost:1235/DuplexDemo'; defURL = 'http://192.168.0.224:1234/DuplexDemo'; defSvc = 'CalculatorService'; defPrt = 'WSDualHttpBinding_IDuplexDemo'; 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 IDuplexDemo); 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; constructor Add.Create; begin inherited Create; FSerializationOptions := [xoLiteralParam]; end; procedure Add.Setn(Index: Integer; const ADouble: Double); begin Fn := ADouble; Fn_Specified := True; end; function Add.n_Specified(Index: Integer): boolean; begin Result := Fn_Specified; end; procedure Add.Setm(Index: Integer; const ADouble: Double); begin Fm := ADouble; Fm_Specified := True; end; function Add.m_Specified(Index: Integer): boolean; begin Result := Fm_Specified; end; constructor Result.Create; begin inherited Create; FSerializationOptions := [xoLiteralParam]; end; procedure Result.Setresult(Index: Integer; const ADouble: Double); begin Fresult := ADouble; Fresult_Specified := True; end; function Result.result_Specified(Index: Integer): boolean; begin Result := Fresult_Specified; end; initialization { IDuplexDemo } InvRegistry.RegisterInterface(TypeInfo(IDuplexDemo), 'http://tempuri.org/', 'utf-8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IDuplexDemo), 'http://tempuri.org/IDuplexDemo/%operationName%'); InvRegistry.RegisterInvokeOptions(TypeInfo(IDuplexDemo), ioDocument); InvRegistry.RegisterInvokeOptions(TypeInfo(IDuplexDemo), ioLiteral); InvRegistry.RegisterInvokeOptions(TypeInfo(IDuplexDemo), ioSOAP12); RemClassRegistry.RegisterXSClass(Add, 'http://tempuri.org/', 'Add'); RemClassRegistry.RegisterSerializeOptions(Add, [xoLiteralParam]); RemClassRegistry.RegisterXSClass(Result, 'http://tempuri.org/', 'Result'); RemClassRegistry.RegisterSerializeOptions(Result, [xoLiteralParam]); end. Danke im Voraus! |
AW: Delphi Client für C# WCF-Service mit wsDualHttp-Binding
Zitat:
Delphi-Quellcode:
var
ws:IDuplexDemo; param:Add; begin params := Add.Create; param.n := 2.2; param.m := 2.8; ws:=GetIDuplexDemo(false); ws.Add(param); end; |
AW: Delphi Client für C# WCF-Service mit wsDualHttp-Binding
Hallo,
vielen Dank für die Antwort! Ich habe es getestet. Jetzt kommt ein Timeout: Das Zeitlimit für den Vorgang wurde erreicht. -URL: ![]() ![]() Auch wenn ich die Timeouts erhöhe kommt es zu diesem Fehler. Hat jemand eine Idee an was das liegen könnte? Mir ist auch immer noch nicht klar wie ich die Callback-Methode, die vom Server abgerufen wird, implementiere. Danke im Voraus! |
AW: Delphi Client für C# WCF-Service mit wsDualHttp-Binding
Zitat:
![]() Um den Callback verarbeiten zu können, benötigt die Delphi Seite einen HTTP Server basierten SOAP Service. Eventuell ist dieser Stackoverflow Artikel hilfreich bei der Implementierung eines Indy-basierten SOAP Servers: ![]() |
AW: Delphi Client für C# WCF-Service mit wsDualHttp-Binding
Wäre es nicht viel einfacher und stabiler, wenn du dir in C# eine Client library baust, die du dann von Delphi aus benutzt? (geht auch ohne COM und Krampf)
Der SOAP-Stack in Delphi war IMO schon immer viel zu unflexibel. Um wieviele Klassen geht es hier? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz