The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,262 other subscribers

TIdHTTPWebBrokerBridge example for a standalone Indy based SOAP service

Posted by jpluimers on 2018/09/12

Since I tend to forget what bits and pieces are needed for TIdHTTPWebBrokerBridge, the below code piece from:

The [WayBack] WebReq.WebRequestHandler Function returns a reference to the global [WayBackTWebRequestHandler object. This object manages all the Web modules in the application, and creates Web request and response objects when the application receives HTTP request messages: TWebRequestHandler keeps a pool of active Web modules. In response to a request from the application, TWebRequestHandler creates a request object and assigns it to one of the active Web modules.

The code below is the Indy counterpart of hooking up a classic WebSnap WebBroker (you could also hook the Web.WebBroker.Application.WebModuleClass to TMyWebModule instead of the WebRequestHandler.WebModuleClass, as Web.WebBroker.Application.WebModuleClass is a TWebApplication which inherits from TWebRequestHandler).

unit Unit2; 
 
interface 
 
uses 
  SysUtils, Classes, Windows, Messages, Variants,  Graphics, Controls, Forms, Dialogs, 
  WebReq, HTTPApp, WSDLPub, SOAPPasInv, SOAPHTTPPasInv, SOAPHTTPDisp, WebBrokerSOAP, 
  InvokeRegistry, SOAPDm, Types, OPConvert, IdHTTPWebBrokerBridge; 
 
type 
  IMyService = interface(IInvokable)         { Invokable interfaces must derive from IInvokable } 
  ['{EB829A60-4B39-4EC8-A684-E4D7BA713036}'] { Methods of Invokable interface must not use the default calling convention; stdcall is recommended } 
    function Hello: String; stdcall; 
  end; 
 
 
type 
  TMyDataModule = class(TSoapDataModule,IMyService) 
  private 
    function Hello:String; stdcall; 
  public 
end; 
 
type 
  TMyWebModule = class(TCustomWebDispatcher) 
    fHTTPSoapDispatcher    : THTTPSoapDispatcher; 
    fHTTPSoapPascalInvoker : THTTPSoapPascalInvoker; 
    fWSDLHTMLPublish       : TWSDLHTMLPublish; 
    procedure DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); 
  private 
 
  public 
    constructor Create(AOwner: TComponent); override; 
    destructor  Destroy;override; 
  end; 
 
type TSOAPServer = class 
  private 
    fWebModule       : TMyWebModule; 
    fWebBrokerBridge : TIdHTTPWebBrokerBridge; 
  public 
    constructor Create(AOwner: TComponent); 
    destructor  Destroy;override; 
end; 
 
implementation 
 
procedure TMyDataModuleCreateInstance(out obj: TObject); 
begin 
  obj := TMyDataModule.Create(nil); 
end; 
 
{ TMyWebModule } 
 
constructor TMyWebModule.Create(AOwner: TComponent); 
begin 
  inherited; 
 
  OldCreateOrder := False; 
  with Actions.Add do begin 
    Default  := True; 
    PathInfo := '/'; 
    Name     := 'DefaultHandler'; 
    OnAction := DefaultHandlerAction; 
  end; 
 
  fHTTPSoapDispatcher                      := THTTPSoapDispatcher.Create(nil); 
  fHTTPSoapPascalInvoker                   := THTTPSoapPascalInvoker.Create(nil); 
  fWSDLHTMLPublish                         := TWSDLHTMLPublish.Create(nil); 
 
  fHTTPSoapPascalInvoker.Converter.Options := [soSendMultiRefObj, soTryAllSchema, soRootRefNodesToBody, soCacheMimeResponse, soUTF8EncodeXML]; 
  fHTTPSoapDispatcher.WebDispatch.PathInfo := 'soap*'; 
 
  fWSDLHTMLPublish.WebDispatch.MethodType  := mtAny; 
  fWSDLHTMLPublish.WebDispatch.PathInfo    := 'wsdl*'; 
 
  fHTTPSoapDispatcher.Dispatcher           := fHTTPSoapPascalInvoker; 
end; 
 
destructor TMyWebModule.Destroy; 
begin 
  FreeAndNil(fHTTPSoapDispatcher); 
  FreeAndNil(fHTTPSoapPascalInvoker); 
  FreeAndNil(fWSDLHTMLPublish); 
  inherited; 
end; 
 
procedure TMyWebModule.DefaultHandlerAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); 
begin 
  fWSDLHTMLPublish.ServiceInfo(Sender, Request, Response, Handled); 
end; 
 
{ TSOAPServer } 
 
constructor TSOAPServer.Create(AOwner: TComponent); 
begin 
//  inherited Create; 
  fWebModule      := TMyWebModule.Create(AOwner); 
 
  InvRegistry.RegisterInterface(TypeInfo(IMyService)); 
  InvRegistry.RegisterInvokableClass(TMyDataModule, TMyDataModuleCreateInstance); 
 
  if WebRequestHandler <> nil then 
    WebRequestHandler.WebModuleClass := TMyWebModule; 
 
  fWebBrokerBridge := TIdHTTPWebBrokerBridge.Create(nil); 
  fWebBrokerBridge.RegisterWebModuleClass(TMyWebModule); 
  fWebBrokerBridge.DefaultPort := 1029; 
  fWebBrokerBridge.Active := True; 
end; 
 
destructor TSOAPServer.Destroy; 
begin 
  fWebBrokerBridge.Active := False; 
  FreeAndNil(fWebModule); 
  FreeAndNil(fWebBrokerBridge); 
  inherited; 
end; 
 
{ TMyDataModule } 
 
function TMyDataModule.hello: String; 
begin 
  Result := 'Hello!!'; 
end; 
 
end.

So i have a class, which can be used like this:

//...
var serv: TSOAPServer;
//...
begin
   serv := TSOAPServer.Create(Form1);
end;

–jeroen

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.