2012-10-25 16 views
6

Próbuję utworzyć aplikację odpoczynku DataSnap działającą jako usługa systemu Windows, ale kreator ma tylko "autonomiczną aplikację VCL", "autonomiczną aplikację konsoli" i "bibliotekę dynamiczną ISAPI "(używam Delphi XE2 enterprise). Ktoś może mi pomóc. Dzięki.DataSnap Rest Server Windows Service Usługa

+1

dlaczego bliskich wniosków? Jak to pytanie nie jest konstruktywne? –

Odpowiedz

4

Byłoby wygodniej, gdyby kreator REST DataSnap miał opcję utworzenia usługi Windows (jak inaczej uruchamiałby się serwer aplikacji?), Ale można obejść go z niewielkim manipulowaniem.

Po pierwszym uruchomieniu tego, stworzyłem regularny serwer REST DataSnap jako aplikację VCL i zwykłą usługę Windows i skopiowałem odpowiednie fragmenty z serwera REST do usługi. Po prostu upewnij się, że katalog wyjściowy dla usługi jest taki sam jak katalog dla aplikacji VCL. .dpr

Serwisu może wyglądać następująco: urządzenie główne

program Service; 

uses 
    Vcl.SvcMgr, 
    Web.WebReq, 
    IdHTTPWebBrokerBridge, 
    WebModuleUnit1 in '..\GUI\WebModuleUnit1.pas' {WebModule1: TWebModule}, 
    ServerMethodsUnit1 in '..\GUI\ServerMethodsUnit1.pas' {ServerMethods1: TDSServerModule}, 
    ServerContainerUnit1 in '..\GUI\ServerContainerUnit1.pas' {ServerContainer1: TDataModule}, 
    Unit1 in 'Unit1.pas' {Service1: TService}; 

{$R *.RES} 

begin 
    if not Application.DelayInitialize or Application.Installing then 
    Application.Initialize; 

    if WebRequestHandler <> nil then 
    WebRequestHandler.WebModuleClass := WebModuleClass; 

    Application.CreateForm(TService1, Service1); 
    Application.Run; 
end. 

Serwisu może wyglądać następująco:

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, 
    Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs, 
    IdHTTPWebBrokerBridge, Web.HTTPApp; 

type 
    TService1 = class(TService) 
    procedure ServiceCreate(Sender: TObject); 
    procedure ServiceExecute(Sender: TService); 
    procedure ServiceStart(Sender: TService; var Started: Boolean); 
    procedure ServiceStop(Sender: TService; var Stopped: Boolean); 
    private 
    FServer: TIdHTTPWebBrokerBridge; 
    procedure TerminateThreads; 
    public 
    function GetServiceController: TServiceController; override; 
    end; 

var 
    Service1: TService1; 

implementation 

{$R *.DFM} 

uses 
    //Datasnap.DSService; // XE2 
    Datasnap.DSSession; // XE3 

procedure ServiceController(CtrlCode: DWord); stdcall; 
begin 
    Service1.Controller(CtrlCode); 
end; 

{ TService1} 

function TService1.GetServiceController: TServiceController; 
begin 
    Result := ServiceController; 
end; 

procedure TService1.ServiceCreate(Sender: TObject); 
begin 
    FServer := TIdHTTPWebBrokerBridge.Create(Self); 
end; 

procedure TService1.ServiceExecute(Sender: TService); 
begin 
    while not Terminated do 
    begin 
    Sleep(1000); 
    ServiceThread.ProcessRequests(False); 
    end; 
end; 

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean); 
begin 
    if not FServer.Active then 
    begin 
    FServer.Bindings.Clear; 
    FServer.DefaultPort := 8080; 
    FServer.Active := True; 
    end; 
end; 

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean); 
begin 
    TerminateThreads; 
    FServer.Active := False; 
    FServer.Bindings.Clear; 

    ServiceThread.Terminate; 
end; 

procedure TService1.TerminateThreads; 
begin 
    if TDSSessionManager.Instance <> nil then 
    TDSSessionManager.Instance.TerminateAllSessions; 
end; 

end. 
+0

Czy Service1.ServiceExecute można pozostawić "pusty" (bez kodu)? – mjn

+0

mjn: Całkiem pewien, że może. –

+0

dziękuję, wypróbuję – JoFan