Einzelnen Beitrag anzeigen

Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#6

Re: 100 Server parallel überprüfen, ob Sie online sind?

  Alt 13. Mai 2010, 03:04
Wenn du mal Threads drauf hast, dann würde ich das ganze wie folgt machen:
  • Erzeuge n Threads, die jeweils m Server nacheinander überprüfen. Natürlich kannst du hier für jeden Server einen Thread erzeugen.
  • Ping innerhalb eines Thread m Server nacheinander an und schicke via SendMessage eine Nachricht an den HauptThread/Klasse (in so fern du eine normale Klasse ohne Handle hast, musst du darin eines via AllocateHWnd erzeugen (DeallocateHWnd nicht vergessen!))
  • Anfänglich kannst du ja ein Array mit n*m Einträge, d.h. für jeden Server einen Eintrag. Drei Werte würde ich einem Server-Status geben: ungeprüft, nicht verfügbar und verfügbar.
  • Via SendMessage kannst du dem MainThread ja die Nachricht zukommen lassen, ob ein Server verfügbar ist oder nicht und feuerst automatisch ein Event, sodass auf eine Änderung eines Status reagiert werden kann.

Hier mal ein wenig Code, frei Hand; sollten also Fehler auftreten, dann garantiere ich für nix

Delphi-Quellcode:
uses
  Classes // hier ist die TThread-Klasse drin
  SysUtils;

const
  WM_SERVER_STATUS = WM_USER + 2;


type

TServerStatus = (ssUnknown, ssOkay, ssUnreachable);

PServerStatusResponse = ^ServerStatusResponse;
RServerStatusResponse = record
  Address : String;
  Status : TServerStatus;
end;

type
TServerCheckThread = class(TThread)
private
  FWatcherHandle : HWND;
  FServerAddress : String;
protected
  procedure Execute(); override;
public
  property WatcherHandle : HWND read FWatcherHandle write FWatcherHandle;
  property ServerAddress : String read FServerAddress write FServerAddress;
end;

procedure TServerCheckThread.Execute();
var
  sr : PServerStatusResponse;
begin
  while (not Terminated) do
  begin
    //
    // Ping ServerAddress...
    //

    New(sr);
    sr^.Address := Self.ServerAddress
    sr^.Status := ... ; // set server status after ping
    SendMessage(FWatcherHandle, WM_SERVER_STATUS, Integer(sr), 0);

    // sleep 10 sec. between two checks...
    SleepEx(10000, True);
  end;
end;

{ ... }

type
TServerWatcher = class(TObject)
private
  FHandle : HWND;
  FWatcherThreads : TList;
  FServerStatus : TStringList;
  procedure WndProc(var Msg:TMessage);
  procedure OnServerStatus(var Msg: TMessage); message WM_SERVER_STATUS;
public
  property Handle : HWND read FHandle;
  constructor Create(); reintroduce;
  destructor Destroy(); override;
  procedure StartWatcherThread(const AServerAddress: String);
end;

procedure TServerWatcher.WndProc(var Msg: TMessage);
begin
  Dispatch(Msg);
end;

procedure TServerWatcher.OnServerStatus(var Msg: TMessage);
var
  sr : PServerStatusResponse
begin
  sr := PServerStatusResponse(msg.WParam);
  try
    FServerStatus.Values[sr^.Address] := ... ; // cast sr^.Status to a good format
  finally
    // free memory (important!)
    Dispose(sr);
  end;
end;

constructor TServerWatcher.Create();
begin
  inherited Create();

  // allocate handle
  FHandle := AllocateHWnd(WndProc);

  // create thread list
  FWachterThreads := TList.Create();

  // create server status list
  FServerStatus := TStringList.Create();
end;

destructor TServerWatcher.Destroy();
var
  i : Integer;
  wt : TWatcherThread;
begin
  // free threads and thread-container
  for i := FWachterThreads.Count - 1 downto 0 do
  begin
    wt := FWachterThreads[i];
    wt.Terminate();
    WaitForSingleObject(FStartupThread.Handle, 1000);
    FreeAndNil(wt);
  end;
  FreeAndNil(FWachterThreads);

  // free server-status list
  FreeAndNil(FServerStatus);

  // free handle
  DeallocateHWnd(FHandle);

  inherited Destroy();
end;

procedure TServerWatcher.StartWatcherThread(const AServerAddress: String);
var
  wt : TWatcherThread;
begin
  // create status for server in list
  FServerStatus.Add(AServerAddress + '=' + ... ); // cast ssUnknown to a good format

  // create sleeping watcher-thread
  wt := TWatcherThread.Create(True);
  wt.WatcherHandle := FHandle;
  wt.ServerAddress := AServerAddress;
  FThreadList.Add(wt);
  wt.Start();
end;
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat