Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Bitte um Hilfe für Webservice/Gateway/PortListener (https://www.delphipraxis.net/170493-bitte-um-hilfe-fuer-webservice-gateway-portlistener.html)

Bali 20. Sep 2012 08:28

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
wow, super :)

dankeschön für die Erfolgsmeldungen :)

Dann würde ich bitte nur noch gerne wissen, wie ich das in Delphi umsetzen kann.

Tobi

Uwe Raabe 20. Sep 2012 08:57

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Kuck mal hier. Vielleicht hilft das schon mal weiter.

mjustin 20. Sep 2012 09:12

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Zitat:

Zitat von Bali (Beitrag 1183665)
Dann würde ich bitte nur noch gerne wissen, wie ich das in Delphi umsetzen kann.

Die Indy Beispiele enthalten sicher auch einen HTTP Server.

Basierend auf diesem Beitrag http://www.delphipraxis.net/238074-post4.html habe ich ungetestet die wesentlichen Teile wiederverwendet:

Delphi-Quellcode:
unit MiniHTTPServer;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPServer, IdCustomHTTPServer,
  IdHTTPServer, StdCtrls, Contnrs;

type
  TForm1 = class(TForm)
    Server: TIdHTTPServer;
    Active: TCheckBox;
    Port: TEdit;

    procedure ServerCommandGet(AThread: TIdPeerThread;
      ARequestInfo: TIdHTTPRequestInfo;
      AResponseInfo: TIdHTTPResponseInfo);

    procedure ActiveClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}



procedure TForm1.ServerCommandGet(AThread: TIdPeerThread;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
  // hier wird die Anfrage bearbeitet.
  // Die URL der Anfrage steht in ARequestInfo.URI,
  // und kann Parameter enthalten.
  // Beispiel "/index.html?data1=wert1&data2=wert2
  // Die Parameter können einzeln ausgelesen werden, Beispiel
  // var1 := ARequestInfo.Params.Values['data1'];

  // Nach der Verarbeitung kann man einen Text zurücksenden (optional)
  AResponseInfo.ContentText:= 'hello world!';

end;

procedure TForm1.ActiveClick(Sender: TObject);
begin
  Try
    If Active.Checked then begin
      Server.DefaultPort:=StrToIntDef(Port.Text,80);
    end;
    Server.Active:=Active.Checked;
  Finally
    Active.Checked:=Server.Active;
  end;
end;

end.
Das Formular enthält nur eine TIdHTTPServer Komponente und ein Editfeld für die Eingabe des Ports, sowie eine Checkbox zum Starten / Stoppen.

Jumpy 20. Sep 2012 09:25

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Service erstellen, einfache Variante:
Datei->Neu->Service-Anwendung

Die Ide erstellt den Rumpf des Programms.
Der TService hat eine Art Form, ist keine richtige Form, aber darauf kann man Komponenten klatschen, z.B. die HttpServer-Komponente von den Indys: IdHttoServer.

Dann ein paar Events des Services einrichten, z.B.:

Delphi-Quellcode:
//----------------------------------------------------------------------
// Service-Events
//----------------------------------------------------------------------

//Damit der Service in der Liste der Dienste
//auch eine vernünftige Beschreibung bekommt:
procedure TPortaleSperrenServer.ServiceAfterInstall(Sender: TService);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\' + Name, false) then
    begin
      Reg.WriteString('Description', ServiceDescription);
      //ServiceDescription ist eine String-Konstante mit der Beschr.
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

procedure TPortaleSperrenServer.ServiceStart(Sender: TService; var Started: Boolean);
begin
  CoInitialize(nil); //Brauch ich wg. Datenbankzugriffen, kann ggf. weg
  //Kann man im Prinzip alles reinmachen, was man sonst vllt.
  //bei Form Create reinmachen würde
end;

procedure TPortaleSperrenServer.ServiceExecute(Sender: TService);
begin
  //Hier auch:
  //Kann man im Prinzip alles reinmachen, was man sonst vllt.
  //bei Form Create reinmachen würde
  Server.Port:=5555;
  SA_Waitlist:=TStringlist.Create;
  Server.Open;

  //Nun die Schleife, in der der Eigentliche Service Thread läuft
  try
    while not Terminated do
      begin
      ServiceThread.ProcessRequests(true); //false
      //Sleep(10);
      end;
  except on E:Exception do
    begin
    LogEvent('Server als Dienst','Letzte Nachricht','',e.Message);
    end;
  end;
end;

procedure TPortaleSperrenServer.ServicePause(Sender: TService; var Paused: Boolean);
begin
  ServerSocket.Close;
end;

procedure TPortaleSperrenServer.ServiceContinue(Sender: TService; var Continued: Boolean);
begin
  Server.Open;
end;

procedure TPortaleSperrenServer.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  Server.Close;
  if SA_WaitList <> nil then SA_WaitList.Free;
  CoUnInitialize;
end;

procedure TPortaleSperrenServer.ServiceShutdown(Sender: TService);
begin
  Server.Close;
  if SA_WaitList <> nil then SA_WaitList.Free;
  CoUnInitialize;
end;

//----------------------------------------------------------------------
// HTTPServer-Events
//----------------------------------------------------------------------
//Einkommende Sendungen vom Programm A:
procedure TMain.HTTPServerCommandGet(AThread: TIdPeerThread;
  RequestInfo: TIdHTTPRequestInfo; ResponseInfo: TIdHTTPResponseInfo);
begin
  //Die direkte weiterleitung der Daten
  if HTTPRedirect then Redirect(RequestInfo.UnparsedParams);
  //Wenn A eine Antwort braucht, das alles angekommen ist:
  if HTTPResponse then
    begin
    ResponseInfo.ResponseNo:=200;
    ResponseInfo.ResponseText:='OK';
    ResponseInfo.WriteContent;
    end;
  //(HTTPRedirect,HTTPResponse = Boolche Konstante):

  //Zur weiterbearbeitung der Daten:
  EvalCallInfo(RequestInfo.Params.Values['event'],
               RequestInfo.Params.Values['date'],
               RequestInfo.Params.Values['src_if'],
               RequestInfo.Params.Values['src_cgpn'],
               RequestInfo.Params.Values['src_cdpn'])
end;

//Die Funktion, um die Daten direkt weiterzusenden.
//Damit könnte man natürlich auch veränderte Daten senden.
//Benutzt wird ein IdHTTP-Client, der immer neu erzeugt wird,
//keine Ahnung, warum das nicht mit einer globalen Kompo gemacht wird
procedure TMain.Redirect(const Params: String);
var
  url:String;
  HTTP: TIdHTTP;
begin
  url:='http://'+RedirectIP+':'+RedirectHost+'/?'+Params;
  HTTP:=TIdHTTP.Create(self);
  try
    HTTP.Get(url);
  finally
    HTTP.Free;
  end;
end;
Hoffe das hilft als start!

mjustin 20. Sep 2012 09:43

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Zitat:

Zitat von Jumpy (Beitrag 1183674)
Service erstellen, einfache Variante

:thumb:

Im Falle eines Indy Servers im Service kann man in ServiceStart Server.Active auf True setzen und bei Stop auf False. Das ServiceExecute kann dann eigentlich wegfallen.

Quellen wie zum Beispiel http://stackoverflow.com/questions/1...service-design (die Antwort enthält den Code für ein Service-Grundgerüst) empfehlen statt ServerExecute, einen eigenen Thread zu starten. Im Falle eines einfachen Indy HTTP Servers wäre das dann dessen Threadpool.

Ich schlage vor einen Eintrag für einen Mini-HTTP Server Service in die Code Library zu stellen :idea:

DeddyH 20. Sep 2012 09:55

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
[OT] Kleiner Hinweis:
Zitat:

Delphi-Quellcode:
if SA_WaitList <> nil then SA_WaitList.Free;

ist doppeltgemoppelt, da Free selbst auf nil prüft. Das ist auch der Grund, wieso man immer Free statt Destroy aufrufen soll. [/OT]

Jumpy 20. Sep 2012 10:28

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Zitat:

Zitat von mjustin (Beitrag 1183681)
Zitat:

Zitat von Jumpy (Beitrag 1183674)
Service erstellen, einfache Variante

:thumb:

Bezog sich darauf, die entsprechenden VCL-Dinge zun nutzen. Es gibt z.B. ja auch aufwendigere Varianten, wo man alles selbst macht, wie z.B. in dem Tutorial vom Delphi-Treff.

Muss auch gestehen, dass in obigem Code, 2 Programme gemixt sind. Der Service nutzt eigentlich nur eine ServerSocket-Komponente. Das mit dem HTTP-Server ist aus einem anderen Programm. Darum ist das da glaub ich ins Execute gepackt worden. Oder läuft eine ServerSocket auch in einem eigenen Threadpool?

Die Empfehlung da generell einen eigenen Thread zu nehmen und beim Service-Start zu starten, hab ich auch von anderen hier (Bummi?) schon öfter gelesen, aber ich hab immer noch Respekt vor eigenen Threads, Kollisionen usw. Einfach zu wenig Gelegenheit das bisher mal einsetzen zu müssen, deswegen die "einfache" Variante, wo einem alles vorbereitet wird.

Jumpy 20. Sep 2012 10:32

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Zitat:

Zitat von DeddyH (Beitrag 1183685)
[OT] Kleiner Hinweis:
Zitat:

Delphi-Quellcode:
if SA_WaitList <> nil then SA_WaitList.Free;

ist doppeltgemoppelt, da Free selbst auf nil prüft. Das ist auch der Grund, wieso man immer Free statt Destroy aufrufen soll. [/OT]

Also egal, ob SA_WaitList
- nie erzeugt wurde (kann hier in dem Bsp. nicht sein, aber generell?) oder
- ob es schon vorher freigegeben wurde,
SA_WaitList.Free funktioniert?

DeddyH 20. Sep 2012 10:33

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Wenn es freigegeben und auf nil gesetzt oder mit nil initialisiert und nie instanziert wurde, richtig.

Bummi 20. Sep 2012 14:11

AW: Bitte um Hilfe für Webservice/Gateway/PortListener
 
Liste der Anhänge anzeigen (Anzahl: 2)
Weil ich mich eine Weile nicht mehr damit beschäftigt hatte ...
Im Anhang eine von TClientSocketThread abgeleitete Klasse und ein kleines Beispiel.
Proxyfuntionalität, Eingriffsmöglichkeit in Request/ResposeStream


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:07 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz