| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 | unit CorrespondService;interfaceuses  ClientInfoService, Classes, IdTCPServer, EncryptService, SysUtils,  SoftDogService, TypeUnit, Windows;type  TThrdsType = (ttTerminate, ttNoDog);  TScMonitor = class  private    FLinkCtrl: TLinkControl;    FCriticalSection: TRTLCriticalSection;  public    constructor Create;    destructor Destroy; override;    procedure AddCount(AUser: Integer);    procedure DeleteCount(AUser: Integer);    function CanNotify(AUser: Integer): Boolean;    procedure SetMaxLinks(const AV0Count, AV1Count, AV2Count: Integer);    procedure InitCount;    procedure NotifyClientInfo(AClientService: TClientInfoDM;      AType: TOperType; APointer: Pointer = nil);    procedure NotifyClientThreads(AClientThrds: TIdPeerThread; AType: TThrdsType);  end;  TScCorrespondService = class  private    FClientInfoService: TClientInfoDM;    FIdTcpServer: TIdTcpServer;    FMonitor: TScMonitor;    FThrdsList: TThreadList;    FPersistent: TScPersistent;    {发送数据加密}    FEncryptService: TScEncryptService;    FSofeDog: TScSoftDog;    function GetPort: Integer;    procedure SetPort(const Value: Integer);    procedure InitMethods;    procedure ClearThrdsInfo;    procedure AddClientThrdsInfo(AThread: TIdPeerThread; AInfo: PInfoRecd);    procedure DeleteClientthrdsInfo(AThread: TIdPeerThread);    procedure DoServerConnect(AThread: TIdPeerThread);    procedure DoServerExecute(AThread: TIdPeerThread);    procedure DoServerDisconnect(AThread: TIdPeerThread);    procedure DoServerException(AThread: TIdPeerThread; AException: Exception);  public    constructor Create;    destructor Destroy; override;    function Open: Boolean;    procedure CloseService;    procedure DeleteClientThrds;    procedure SetMaxLinks(const AV0Count, AV1Count, AV2Count: Integer);    property Port: Integer read GetPort write SetPort;    property SoftDog: TScSoftDog write FSofeDog;    property ClientInfoService: TClientInfoDM read FClientInfoService write FClientInfoService;  end;implementation{ TScMonitor }procedure TScMonitor.AddCount(AUser: Integer);begin  FLinkCtrl.AddCount(AUser);end;function TScMonitor.CanNotify(AUser: Integer): Boolean;begin  Result := not FLinkCtrl.CheckIsFull(AUser);end;constructor TScMonitor.Create;begin  FLinkCtrl := TLinkControl.Create;  InitializeCriticalSection(FCriticalSection);end;procedure TScMonitor.DeleteCount(AUser: Integer);begin  FLinkCtrl.DeleteCount(AUser);end;destructor TScMonitor.Destroy;begin  FLinkCtrl.Free;  DeleteCriticalSection(FCriticalSection);  inherited;end;procedure TScMonitor.InitCount;begin  FLinkCtrl.InitCount;end;procedure TScMonitor.NotifyClientInfo(AClientService: TClientInfoDM;  AType: TOperType; APointer: Pointer);begin  EnterCriticalSection(FCriticalSection);  try    AClientService.HandlerNotify(AType, APointer);  finally    LeaveCriticalSection(FCriticalSection);  end;end;procedure TScMonitor.NotifyClientThreads(AClientThrds: TIdPeerThread;  AType: TThrdsType);begin  if AType = ttTerminate then  begin    AClientThrds.Connection.Disconnect;  end;end;procedure TScMonitor.SetMaxLinks(const AV0Count, AV1Count,  AV2Count: Integer);begin  FLinkCtrl.V0MaxLinks := AV0Count;  FLinkCtrl.V1MaxLinks := AV1Count;  FLinkCtrl.V2MaxLinks := AV2Count;end;{ TScCorrespondService }procedure TScCorrespondService.CloseService;{var  I: Integer;  thsList: TList;  sText: string;  thrds: TIdPeerThread;  }begin  if not FIdTcpServer.Active then Exit;  {  thsList := FIdTcpServer.Threads.LockList;  try    for I := thsList.Count - 1 downto 0 do    begin      thrds := TIdPeerThread(thsList.List^[I]);      sText := FEncryptService.EncryptString('QUITOUT');      thrds.Connection.WriteLn(sText);    end;  finally    FIdTcpServer.Threads.UnlockList;  end;      }    FMonitor.InitCount;  FMonitor.NotifyClientInfo(FClientInfoService, otDelete);  ClearThrdsInfo;  FIdTcpServer.Active := False;end;constructor TScCorrespondService.Create;begin  FIdTcpServer := TIdTCPServer.Create(nil);  FMonitor := TScMonitor.Create;  FEncryptService := TScEncryptService.Create;  FPersistent := TScPersistent.Create;  FPersistent.ReadPersistentProperty;  FThrdsList := TThreadList.Create;  InitMethods;end;destructor TScCorrespondService.Destroy;begin  CloseService;  FIdTcpServer.Free;  FMonitor.Free;  FEncryptService.Free;  FPersistent.WritePersistentProperty;  FPersistent.Free;  ClearThrdsInfo;  FThrdsList.Free;  inherited;end;function TScCorrespondService.GetPort: Integer;begin  Result := FPersistent.Port;end;procedure TScCorrespondService.DoServerConnect(AThread: TIdPeerThread);beginend;procedure TScCorrespondService.DoServerDisconnect(  AThread: TIdPeerThread);beginend;procedure TScCorrespondService.DoServerException(AThread: TIdPeerThread;  AException: Exception);var  I: Integer;  ptThrds: PThrdsRecd;  infoRec: PInfoRecd;  lstThrds: TList;begin  AThread.Connection.Disconnect;  New(infoRec);  lstThrds := FThrdsList.LockList;  try    for I := 0 to lstThrds.Count - 1 do    begin      ptThrds := lstThrds.List^[I];      if AThread = ptThrds.Thread then      begin        infoRec.IP := ptThrds.IP;        infoRec.User := ptThrds.User;        FMonitor.NotifyClientInfo(FClientInfoService, otDelete, infoRec);        FMonitor.DeleteCount(infoRec.User);        lstThrds.Delete(I);        Dispose(ptThrds);        Break;      end;    end;  finally    FThrdsList.UnlockList;    Dispose(infoRec);  end;end;procedure TScCorrespondService.DoServerExecute(AThread: TIdPeerThread);var  infoRec: PInfoRecd;  strText: string;begin  if AThread.Connection.Server.Active and not AThread.Terminated then  begin    strText := AThread.Connection.ReadLn(#13#10, 1000, 100);    New(infoRec);    FEncryptService.DeEncryptString(strText, infoRec);    if infoRec.Action = 0 then  {链接}    begin      if FMonitor.CanNotify(infoRec.User) then      begin        FMonitor.NotifyClientInfo(FClientInfoService, otAdd, infoRec);        strText := FEncryptService.EncryptString('SUCCESS');        AThread.Connection.WriteLn(strText);        FMonitor.AddCount(infoRec.User);        AddClientThrdsInfo(AThread, infoRec);      end      else      begin        strText := FEncryptService.EncryptString('ISFULL');        AThread.Connection.WriteLn(strText);      end;    end    else if infoRec.Action = 1 then  {断开}    begin      FMonitor.NotifyClientInfo(FClientInfoService, otDelete, infoRec);      FMonitor.DeleteCount(infoRec.User);      DeleteClientthrdsInfo(AThread);    end    else if infoRec.Action = 9 then  {检测}    begin      strText := FSofeDog.ReadData(StrToInt(infoRec.IP), infoRec.User);      strText := FEncryptService.EncryptString(strText);      AThread.Connection.WriteLn(strText);      FMonitor.NotifyClientInfo(FClientInfoService, otModify, infoRec);    end;    Dispose(infoRec);  end;end;procedure TScCorrespondService.InitMethods;begin//  FIdTcpServer.OnConnect := DoServerConnect;  FIdTcpServer.OnExecute := DoServerExecute;//  FIdTcpServer.OnDisconnect := DoServerDisconnect;  FIdTcpServer.OnException := DoServerException;end;function TScCorrespondService.Open: Boolean;begin  Result := True;  if FIdTcpServer.Active then Exit;    FIdTcpServer.Bindings.Clear;  FIdTcpServer.Threads.Clear;  FIdTcpServer.DefaultPort := Port;  try    FIdTcpServer.Active := True;  except    Result := False;  end;end;procedure TScCorrespondService.SetPort(const Value: Integer);begin  FPersistent.Port := Value;end;procedure TScCorrespondService.SetMaxLinks(const AV0Count, AV1Count,  AV2Count: Integer);begin  FMonitor.SetMaxLinks(AV0Count, AV1Count, AV2Count);end;procedure TScCorrespondService.DeleteClientThrds;var  I, iUser: Integer;  strIP: string;  lstThrds: TList;  thrds: PThrdsRecd;begin  iuser := FClientInfoService.CurUser;  strIP := FClientInfoService.CurIP;  lstThrds := FThrdsList.LockList;  try    for I := 0 to lstThrds.Count - 1 do    begin      thrds := lstThrds.List^[I];      if SameText(thrds.IP, strIP) and (iUser = thrds.User) then      begin        if Assigned(thrds.Thread.Connection) then          thrds.Thread.Connection.DisconnectSocket;        FClientInfoService.DeleteCurRecord;        FMonitor.DeleteCount(iUser);        lstThrds.Delete(I);        Dispose(thrds);        Break;      end;    end;  finally    FThrdsList.UnlockList;  end;end;procedure TScCorrespondService.AddClientThrdsInfo(AThread: TIdPeerThread;  AInfo: PInfoRecd);var  I: Integer;  blFlag: Boolean;  lstThrds: TList;  ptThrds: PThrdsRecd;begin  blFlag := False;  lstThrds := FThrdsList.LockList;  try    for I := 0 to lstThrds.Count - 1 do    begin      ptThrds := lstThrds.List^[I];      if AThread = ptThrds.Thread then      begin        blFlag := True;        Break;      end;    end;    if not blFlag then    begin      New(ptThrds);      ptThrds.Thread := AThread;      ptThrds.IP := AInfo.IP;      ptThrds.User := AInfo.User;      lstThrds.Add(ptThrds);    end;  finally    FThrdsList.UnlockList;  end;end;procedure TScCorrespondService.DeleteClientthrdsInfo(  AThread: TIdPeerThread);var  I: Integer;  lstThrds: TList;  ptThrds: PThrdsRecd;begin  lstThrds := FThrdsList.LockList;  try    for I := 0 to lstThrds.Count - 1 do    begin      ptThrds := lstThrds.List^[I];      if AThread = ptThrds.Thread then      begin        lstThrds.Delete(I);        Dispose(ptThrds);        Break;      end;    end;  finally    FThrdsList.UnlockList;  end;end;procedure TScCorrespondService.ClearThrdsInfo;var  I: Integer;  lstThrds: TList;  thrdsRec: PThrdsRecd;begin  lstThrds := FThrdsList.LockList;  try    for I := 0 to lstThrds.Count - 1 do    begin      thrdsRec := lstThrds.List^[I];      Dispose(thrdsRec);    end;  finally    FThrdsList.UnlockList;  end;  FThrdsList.Clear;end;end.
 |