Search code examples
delphiindytadodataset

Building HTTP Server Application


I have a project which does financial reports and I want to let user to be able to get this reports through the internet

I tried using TIdHTTPServer which is an Indy component to make my application to work as an HTTP Server and to let it to be able

receive request -> process the request -> send back the result of the request process

using a special port.

now my problem is that I'm getting a lot of Access Violation errors and random exceptions it looks like about threads problem or I don't know because if I process the same request without using the TIdHTTPServer I don't get any problem

i'm using the OnCommandGet Event to process the request and send the result back to user inside the context stream.

what I need is a demonstration on how to use it with TADODataSet and TADOConnection

for example I need the user to be able to send a request and the TIdHTTPServer takes the request (for example call a stored procedure using to ADODataSet and take the result as XML file and send it back to the user)

please help....thank you.


Solution

  • one possibility how a Server could work ...

    unit Unit3;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs,IDContext, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer, StdCtrls, DB, ADODB;
    
    type
      TForm3 = class(TForm)
        IdTCPServer1: TIdTCPServer;
        Memo1: TMemo;
        Button1: TButton;
        DummyConnection: TADOConnection;
        procedure Button1Click(Sender: TObject);
        procedure IdTCPServer1Execute(AContext: TIdContext);
      private
        { Private-Deklarationen }
      public
        { Public-Deklarationen }
      end;
    
    var
      Form3: TForm3;
    
    implementation
    uses ComObj,AdoInt,ActiveX;
    {$R *.dfm}
    function SendStream(AContext: TIdContext; AStream: TStream): Boolean;
    begin
       Result := False;
       try
         AContext.Connection.IOHandler.Write(AStream.Size);  // sending length of Stream first
         AContext.Connection.IOHandler.WriteBufferOpen;
         AContext.Connection.IOHandler.Write(AStream, AStream.Size);
         AContext.Connection.IOHandler.WriteBufferFlush;
       finally
         AContext.Connection.IOHandler.WriteBufferClose;
       end;
       Result := True;
    end;
    
    procedure TForm3.Button1Click(Sender: TObject);
    begin
      IdTCPServer1.Active := true;
    end;
    
    
    { Clientside function
    Function RecordsetFromXMLStream(Stream:TStream): _Recordset;
    var
      RS: Variant;
    begin
        RS := CreateOleObject('ADODB.Recordset');
        RS.Open(TStreamAdapter.Create(Stream) as IUnknown);
        Result := IUnknown(RS) as _Recordset;
    end;
    }
    
    Procedure RecordsetToXMLStream(const Recordset: _Recordset;Stream:TStream);
    var
      RS: Variant;
    begin
        if Recordset = nil then Exit;
        RS := CreateOleObject('ADODB.Recordset');
        RS := Recordset;
        RS.Save(TStreamAdapter.Create(stream) as IUnknown, adPersistXML);
        Stream.Position := 0;
    end;
    
    Procedure GetQueryStream(Const s,ConStr:String;ms:TMemoryStream);
    var
     AC:TAdoConnection;
     ads:TAdodataset;
    begin
     AC:=TAdoConnection.Create(nil);
     try
     ads:=TAdodataset.Create(nil);
       try
         ads.Connection := AC;
         AC.ConnectionString := ConStr;
         ads.CommandText := s;
         ads.Open;
         RecordsetToXMLStream(ads.Recordset,ms);
       finally
         ads.Free
       end;
     finally
       AC.Free
     end;
    
    end;
    
    procedure TForm3.IdTCPServer1Execute(AContext: TIdContext);
    var
     cmd:String;
     ms:TMemoryStream;
    begin
         CoInitialize(nil);
         AContext.Connection.IOHandler.Readln(cmd);
         ms:=TMemoryStream.Create;
         try
         GetQueryStream('Select * from Adressen',DummyConnection.ConnectionString,ms);
         ms.Position := 0;
         SendStream(AContext,ms);
         AContext.Connection.Socket.CloseGracefully;
         finally
            ms.Free;
            CoUninitialize;
         end;
    
    end;
    end.