2011-04-05 1 views
3

J'ai créé un service web dans Delphi XE en utilisant l'importateur WSDL. Delphi a généré pour moi le module ITransmitter1.pas avec Interface ITransmitter et fonction GetITransmitter.Comment fonctionnent les services web Delphi? (Ajout de méthode en runtime ??)

Pour utiliser webservice-je utiliser:

var Transmitter: ITransmitter; 
begin 
    Transmitter := GetITransmitter(True, '', nil); 
    Transmitter.Transmit(Memo1.Text, OutXML); 
end; 

Mais je ne peux pas voir partout le corps de la méthode de transmission ...

En ITransmitter.pas je vois:

InvRegistry.RegisterInterface(TypeInfo(ITransmitter), 'urn:TransmitterIntf-ITransmitter', 'utf-8'); 
    InvRegistry.RegisterDefaultSOAPAction(TypeInfo(ITransmitter), 'urn:TransmitterIntf-ITransmitter#Transmit'); 

Si je commente cette ligne je reçois l'erreur "interface non supporté". Comme je le vois ici, delphi ajoute une méthode dans RunTime! Comment ça marche? Puis-je ajouter une méthode en cours d'exécution à ma propre classe?

Répondre

2

Si vous avez créé un client de service Web avec l'importateur WSDL, le code client généré appelle une méthode sur le serveur. Donc en fait, la méthode 'body' (code) est sur le serveur de service web. Delphi génère une requête de savon basée sur le langage WSDL, et derrière la scène RTTI (introspection) est utilisée pour générer des paramètres etc. de l'appel de service Web en tant que XML. Ce code XML est envoyé au serveur, qui exécute l'implémentation de la méthode et renvoie une réponse Soap.

Les choses sont opposées si vous créez le serveur de service Web, dans ce cas l'application Delphi doit bien sûr implémenter tous les corps de méthode.

+0

Je ne peux pas déboguer ma méthode Transmitter.Transmit. Et je me demande encore quelle méthode est en fait exécutée quand j'appelle Transmitter.Transmit? Habituellement, quand j'appelle une méthode, je vois le code placé dans un fichier .pas. Maintenant, je n'ai aucune idée de ce qui se passe réellement quand j'appelle cette méthode ... – Astronavigator

1

Vous appelez en fait une méthode définie dans une interface, qui à son tour hérite de IInvokable, déclarée dans System.pas. Si vous vérifiez votre code source, vous remarquerez qu'aucun objet local dans votre projet n'implémente l'interface IInvokable que vous appelez, car cette méthode est exécutée à distance sur le serveur. Avant que cela se produise, un code pascal est utilisé pour créer une requête SOAP correcte sur le serveur, l'envoyer, puis attendre et interpréter la réponse du serveur, examiner les détails de l'implémentation. Si vous souhaitez en savoir un peu plus comment cela fonctionne, activez l'option de compilateur "use debug .dcus" pour pouvoir déboguer dans VCL/RTL. Puis, comme d'habitude, utilisez la commande StepInto (F7) pour demander au débogueur d'exécuter la méthode Transmit pas à pas ... après un assembleur dans la méthode TRIO.GenericStub, vous obtiendrez la méthode TRIO.Generic où le paquet est préparé et envoyé.

Pour une fixation btSOAP j'utilise pour écrire cette réponse, la partie pertinente commence à la ligne 943 dans l'unité Rio.pas:

try 
     FWebNode.Execute(Req, Resp); 
    finally 
     { Clear Outbound headers } 
     FHeadersOutBound.Clear; 
    end;   

THTTPReqResp.Execute utilise ensuite les fonctions Wininet.dll pour effectuer la connexion, envoyer et recevoir des informations avec le serveur en utilisant.

Il y a quelques niveaux que vous pouvez aller en profondeur avec ceci ... jusqu'où vous voulez aller dépendra de vos intérêts et la grande quantité de détails sont bien au-delà de la portée de ma réponse ici ... n'hésitez pas à poster plus de questions avec des tings spécifiques qui vous intéressent

Je ne suis pas sûr de, mais les détails peuvent changer entre les versions de Delphi ... J'utilise Delphi XE dès maintenant.

+0

OK. Ce que je vois est: L'objet Transmitter a été généré par la fonction GetITTransmitter. Cette fonction génère le résultat de cette façon: RIO: = THTTPRIO.Create (nil); Résultat: = (RIO comme ITransmitter); Donc, la réallocation de la méthode Transmit doit être dans la classe THTTPRIO. Mais comme je vois il n'y en a pas. Donc, comme je comprends chaque fois que j'appelle une méthode de l'émetteur, peu importe lequel, en fait TRIO.GenericStub sera exécuté. Alors je peux faire ma propre classe avec cet avenir? Je meen classe telle classe, donc peu importe quelle méthode j'appelle, de toute façon Delphi appellera une méthode fixe? – Astronavigator

+0

@Astronavigator: ITransmitter est une interface générée par Delphi lors du traitement du WDSL par l'importateur WDSL. En bref, la méthode générique est appelée pour toute méthode d'interface que vous appelez. Il n'y a pas d'objet réel où cette méthode est définie côté client: l'interface est définie pour votre commodité, vous pouvez interagir avec le service Web de la même manière qu'avec d'autres objets de votre application. Les classes THTTPRio/TRio utilisent la méthode QueryInterface standard invoquée tandis que l'opérateur AS convertit l'objet en interface pour générer une VTable à la volée afin d'effectuer ce mappage. – jachguate

+0

Jetez un coup d'oeil à la méthode TRio.GenVTable, qui est appelée lors du traitement de la QueryInterface. L'unité est soap \ Rio.pas – jachguate

Questions connexes