Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 428
user1512094 Avatar asked Mar 13 '26 05:03

user1512094


1 Answers

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.
like image 185
bummi Avatar answered Mar 14 '26 21:03

bummi