Applications service

De RAD Studio
Aller à : navigation, rechercher

Remonter à Création d'applications

Les applications service reçoivent les requêtes des applications client, traitent ces requêtes et renvoient les informations aux applications client. Habituellement, elles s'exécutent en arrière-plan, sans nécessiter de saisie utilisateur importante. Un serveur Web, FTP ou de messagerie électronique est un exemple d'application service.

Pour créer une application qui implémente un service Win32 :

  1. Choisissez Fichier > Nouveau > Autre et double-cliquez sur Application Service dans la boîte de dialogue Nouveaux éléments. Cela ajoute à votre projet une variable globale appelée Application de type TServiceApplication.
  2. La fenêtre Service qui apparaît correspond à un service (TService). Implémentez le service en initialisant ses propriétés et ses gestionnaires d'événements dans l'inspecteur d'objets.
  3. Vous pouvez ajouter des services supplémentaires en choisissant Fichier > Nouveau > Autre et en double-cliquant sur Service dans la boîte de dialogue Nouveaux éléments. N'ajoutez pas de services à une application qui n'est pas une application service. En effet, même si un objet TService est ajouté, l'application ne génère pas les événements nécessaires, ni ne fait les appels Windows appropriés au service.
  4. Une fois que votre application service est construite, vous pouvez installer ses services avec le SCM (Service Control Manager). Les autres applications peuvent alors lancer vos services en envoyant des requêtes au SCM.

Pour installer les services de votre application, exécutez-la à l'aide de l'option /INSTALL. L'application installe ses services puis quitte, en affichant un message de confirmation si les services sont correctement installés. Vous pouvez supprimer l'affichage du message de confirmation en exécutant l'application service à l'aide de l'option /SILENT.

Pour désinstaller les services de votre application, exécutez-la depuis la ligne de commande à l'aide de l'option /UNINSTALL. (Vous pouvez aussi utiliser l'option /SILENT pour supprimer le message de confirmation lors de la désinstallation).

Remarque :   Le service suivant contient un TServerSocket dont le port est initialisé à 80. C'est le port par défaut des navigateurs Web pour envoyer des requêtes à des serveurs Web et celui utilisé par les serveurs Web pour répondre aux navigateurs Web. Cet exemple spécifique produit, dans le répertoire C:\Temp, un document texte appelé WebLogxxx.log (où xxx correspond au ThreadID). Il ne doit y avoir qu'un seul serveur surveillant un port donné, donc si vous utilisez déjà un serveur Web, vous devez vous assurer qu'il n'est pas à l'écoute (le service doit être arrêté).

Pour voir les résultats : ouvrez un navigateur Web sur la machine locale, et pour l'adresse, entrez 'localhost' (sans les apostrophes). Eventuellement, le navigateur va faire une erreur de dépassement de délai mais vous devez obtenir un fichier appelé Weblogxxx.log dans le répertoire C:\Temp.

Pour créer l'exemple :

  1. Choisissez Fichier > Nouveau > Autre et sélectionnez Application Service dans la boîte de dialogue Nouveaux éléments. La fenêtre Service1 apparaît.
  2. Ajoutez un composant ServerSocket de la catégorie Internet de la palette d'outils à la fenêtre service (Service1).
  3. Ajoutez une donnée membre privée de type TMemoryStream à la classe TService1. La section interface de l'unité doit ressembler à :
 
 interface
 uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
   ScktComp;
 type
     TService1 = class(TService)
     ServerSocket1: TServerSocket;
     procedure ServerSocket1ClientRead(Sender: TObject;
       Socket: TCustomWinSocket);
     procedure Service1Execute(Sender: TService);
   private
     { Déclarations privées }
     Stream: TMemoryStream; // Ajoutez cette ligne ici
   public
     function GetServiceController: PServiceController; override;
     { Déclarations publiques }
   end;
 var
   Service1: TService1;
 //---------------------------------------------------------------------------
 #ifndef Unit1H
 #define Unit1H
 //---------------------------------------------------------------------------
 #include <SysUtils.hpp>
 #include <Classes.hpp>
 #include <SvcMgr.hpp>
 #include <ScktComp.hpp>
 //---------------------------------------------------------------------------
 class TService1 : public TService
 {
 __published:
 TServerSocket *ServerSocket1;
 private:
 TMemoryStream *Stream; // ajoutez cette ligne
 public:
 __fastcall TService1(TComponent* Owner);
 PServiceController __fastcall GetServiceController(void);
 friend void __stdcall ServiceController(unsigned CtrlCode);
 };
 //---------------------------------------------------------------------------
 extern PACKAGE TService1 *Service1;
 //---------------------------------------------------------------------------
 #endif
  1. Sélectionnez ServerSocket1, le composant ajouté à l'étape 1. Dans l'inspecteur d'objets, double-cliquez sur l'événement OnClientRead et ajoutez le gestionnaire d'événement suivant :
 
 procedure TService1.ServerSocket1ClientRead(Sender: TObject;
   Socket: TCustomWinSocket);
 var
   Buffer: PChar;
 begin
   Buffer := nil;
 while Socket.ReceiveLength > 0 do begin
     Buffer := AllocMem(Socket.ReceiveLength);
     try
       Socket.ReceiveBuf(Buffer^, Socket.ReceiveLength);
       Stream.Write(Buffer^, StrLen(Buffer));
     finally
 				  FreeMem(Buffer);
     end;
   Stream.Seek(0, soFromBeginning);
   Stream.SaveToFile('c:\Temp\Weblog' + IntToStr(ServiceThread.ThreadID) + '.log');
   end;
 end;
 void __fastcall TService1::ServerSocket1ClientRead(TObject *Sender,
 TCustomWinSocket *Socket)
 {
 char *Buffer = NULL;
 int len = Socket->ReceiveLength();
 while (len > 0)
 {
 try
 {
 Buffer = (char *)malloc(len);
 Socket->ReceiveBuf((void *)Buffer, len);
 Stream->Write(Buffer, len);
 }
 __finally
 {
 free(Buffer);
 }
 Stream->Seek(0, soFromBeginning);
 AnsiString LogFile = "C:\\Temp\\WebLog";
 LogFile = LogFile + IntToStr(ServiceThread->ThreadID) + ".log";
 Stream->SaveToFile(LogFile);
 }
 }
  1. Sélectionnez enfin Service1 en cliquant sur la zone client de la fenêtre (mais pas sur le composant ServiceSocket). Dans l'inspecteur d'objets, double-cliquez sur l'événement OnExecute et ajoutez le gestionnaire d'événement suivant :
 
 procedure TService1.Service1Execute(Sender: TService);
 begin
   Stream := TMemoryStream.Create;
   try
     ServerSocket1.Port := 80; // port WWW
     ServerSocket1.Active := True;
     while not Terminated do begin
       ServiceThread.ProcessRequests(True);
     end;
     ServerSocket1.Active := False;
   finally
     Stream.Free;
   end;
 end;
 void __fastcall TService1::Service1Execute(TService *Sender)
 {
 Stream = new TMemoryStream();
 try
 {
 ServerSocket1->Port = 80; // Port WWW
 ServerSocket1->Active = true;
 while (!Terminated)
 ServiceThread->ProcessRequests(true);
 ServerSocket1->Active = false;
 }
 __finally
 {
 delete Stream;
 }
 }

Remarque :   Les applications service ne peuvent pas être utilisées pour les applications multiplates-formes.

Rubriques

Voir aussi