Создание приложения HTTP-сервера
У меня есть проект, который делает финансовые отчеты, и я хочу, чтобы пользователь мог получать эти отчеты через Интернет
Я попытался использовать TIdHTTPServer, который является компонентом Indy, чтобы заставить мое приложение работать как HTTP-сервер и позволить ему работать
получить запрос -> обработать запрос -> отправить результат обработки запроса
используя специальный порт.
Теперь моя проблема в том, что я получаю много ошибок Access Violation и случайных исключений, похоже на проблему с потоками, или я не знаю, потому что, если я обрабатываю тот же запрос без использования TIdHTTPServer, у меня не возникает никаких проблем.
Я использую событие OnCommandGet для обработки запроса и отправки результата обратно пользователю в потоке контекста.
что мне нужно, это демонстрация того, как использовать его с TADODataSet и TADOConnection
например, мне нужно, чтобы пользователь мог отправлять запрос, а TIdHTTPServer принимает запрос (например, вызывает хранимую процедуру с использованием ADODataSet, принимает результат в виде файла XML и отправляет его обратно пользователю)
пожалуйста, помогите.... спасибо.
1 ответ
Одна возможность, как сервер может работать...
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.