CorrespondService.pas 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. unit CorrespondService;
  2. interface
  3. uses
  4. ClientInfoService, Classes, IdTCPServer, EncryptService, SysUtils,
  5. SoftDogService, TypeUnit, Windows;
  6. type
  7. TThrdsType = (ttTerminate, ttNoDog);
  8. TScMonitor = class
  9. private
  10. FLinkCtrl: TLinkControl;
  11. FCriticalSection: TRTLCriticalSection;
  12. public
  13. constructor Create;
  14. destructor Destroy; override;
  15. procedure AddCount(AUser: Integer);
  16. procedure DeleteCount(AUser: Integer);
  17. function CanNotify(AUser: Integer): Boolean;
  18. procedure SetMaxLinks(const AV0Count, AV1Count, AV2Count: Integer);
  19. procedure InitCount;
  20. procedure NotifyClientInfo(AClientService: TClientInfoDM;
  21. AType: TOperType; APointer: Pointer = nil);
  22. procedure NotifyClientThreads(AClientThrds: TIdPeerThread; AType: TThrdsType);
  23. end;
  24. TScCorrespondService = class
  25. private
  26. FClientInfoService: TClientInfoDM;
  27. FIdTcpServer: TIdTcpServer;
  28. FMonitor: TScMonitor;
  29. FThrdsList: TThreadList;
  30. FPersistent: TScPersistent;
  31. {发送数据加密}
  32. FEncryptService: TScEncryptService;
  33. FSofeDog: TScSoftDog;
  34. function GetPort: Integer;
  35. procedure SetPort(const Value: Integer);
  36. procedure InitMethods;
  37. procedure ClearThrdsInfo;
  38. procedure AddClientThrdsInfo(AThread: TIdPeerThread; AInfo: PInfoRecd);
  39. procedure DeleteClientthrdsInfo(AThread: TIdPeerThread);
  40. procedure DoServerConnect(AThread: TIdPeerThread);
  41. procedure DoServerExecute(AThread: TIdPeerThread);
  42. procedure DoServerDisconnect(AThread: TIdPeerThread);
  43. procedure DoServerException(AThread: TIdPeerThread; AException: Exception);
  44. public
  45. constructor Create;
  46. destructor Destroy; override;
  47. function Open: Boolean;
  48. procedure CloseService;
  49. procedure DeleteClientThrds;
  50. procedure SetMaxLinks(const AV0Count, AV1Count, AV2Count: Integer);
  51. property Port: Integer read GetPort write SetPort;
  52. property SoftDog: TScSoftDog write FSofeDog;
  53. property ClientInfoService: TClientInfoDM read FClientInfoService write FClientInfoService;
  54. end;
  55. implementation
  56. { TScMonitor }
  57. procedure TScMonitor.AddCount(AUser: Integer);
  58. begin
  59. FLinkCtrl.AddCount(AUser);
  60. end;
  61. function TScMonitor.CanNotify(AUser: Integer): Boolean;
  62. begin
  63. Result := not FLinkCtrl.CheckIsFull(AUser);
  64. end;
  65. constructor TScMonitor.Create;
  66. begin
  67. FLinkCtrl := TLinkControl.Create;
  68. InitializeCriticalSection(FCriticalSection);
  69. end;
  70. procedure TScMonitor.DeleteCount(AUser: Integer);
  71. begin
  72. FLinkCtrl.DeleteCount(AUser);
  73. end;
  74. destructor TScMonitor.Destroy;
  75. begin
  76. FLinkCtrl.Free;
  77. DeleteCriticalSection(FCriticalSection);
  78. inherited;
  79. end;
  80. procedure TScMonitor.InitCount;
  81. begin
  82. FLinkCtrl.InitCount;
  83. end;
  84. procedure TScMonitor.NotifyClientInfo(AClientService: TClientInfoDM;
  85. AType: TOperType; APointer: Pointer);
  86. begin
  87. EnterCriticalSection(FCriticalSection);
  88. try
  89. AClientService.HandlerNotify(AType, APointer);
  90. finally
  91. LeaveCriticalSection(FCriticalSection);
  92. end;
  93. end;
  94. procedure TScMonitor.NotifyClientThreads(AClientThrds: TIdPeerThread;
  95. AType: TThrdsType);
  96. begin
  97. if AType = ttTerminate then
  98. begin
  99. AClientThrds.Connection.Disconnect;
  100. end;
  101. end;
  102. procedure TScMonitor.SetMaxLinks(const AV0Count, AV1Count,
  103. AV2Count: Integer);
  104. begin
  105. FLinkCtrl.V0MaxLinks := AV0Count;
  106. FLinkCtrl.V1MaxLinks := AV1Count;
  107. FLinkCtrl.V2MaxLinks := AV2Count;
  108. end;
  109. { TScCorrespondService }
  110. procedure TScCorrespondService.CloseService;
  111. {var
  112. I: Integer;
  113. thsList: TList;
  114. sText: string;
  115. thrds: TIdPeerThread; }
  116. begin
  117. if not FIdTcpServer.Active then Exit;
  118. { thsList := FIdTcpServer.Threads.LockList;
  119. try
  120. for I := thsList.Count - 1 downto 0 do
  121. begin
  122. thrds := TIdPeerThread(thsList.List^[I]);
  123. sText := FEncryptService.EncryptString('QUITOUT');
  124. thrds.Connection.WriteLn(sText);
  125. end;
  126. finally
  127. FIdTcpServer.Threads.UnlockList;
  128. end; }
  129. FMonitor.InitCount;
  130. FMonitor.NotifyClientInfo(FClientInfoService, otDelete);
  131. ClearThrdsInfo;
  132. FIdTcpServer.Active := False;
  133. end;
  134. constructor TScCorrespondService.Create;
  135. begin
  136. FIdTcpServer := TIdTCPServer.Create(nil);
  137. FMonitor := TScMonitor.Create;
  138. FEncryptService := TScEncryptService.Create;
  139. FPersistent := TScPersistent.Create;
  140. FPersistent.ReadPersistentProperty;
  141. FThrdsList := TThreadList.Create;
  142. InitMethods;
  143. end;
  144. destructor TScCorrespondService.Destroy;
  145. begin
  146. CloseService;
  147. FIdTcpServer.Free;
  148. FMonitor.Free;
  149. FEncryptService.Free;
  150. FPersistent.WritePersistentProperty;
  151. FPersistent.Free;
  152. ClearThrdsInfo;
  153. FThrdsList.Free;
  154. inherited;
  155. end;
  156. function TScCorrespondService.GetPort: Integer;
  157. begin
  158. Result := FPersistent.Port;
  159. end;
  160. procedure TScCorrespondService.DoServerConnect(AThread: TIdPeerThread);
  161. begin
  162. end;
  163. procedure TScCorrespondService.DoServerDisconnect(
  164. AThread: TIdPeerThread);
  165. begin
  166. end;
  167. procedure TScCorrespondService.DoServerException(AThread: TIdPeerThread;
  168. AException: Exception);
  169. var
  170. I: Integer;
  171. ptThrds: PThrdsRecd;
  172. infoRec: PInfoRecd;
  173. lstThrds: TList;
  174. begin
  175. AThread.Connection.Disconnect;
  176. New(infoRec);
  177. lstThrds := FThrdsList.LockList;
  178. try
  179. for I := 0 to lstThrds.Count - 1 do
  180. begin
  181. ptThrds := lstThrds.List^[I];
  182. if AThread = ptThrds.Thread then
  183. begin
  184. infoRec.IP := ptThrds.IP;
  185. infoRec.User := ptThrds.User;
  186. FMonitor.NotifyClientInfo(FClientInfoService, otDelete, infoRec);
  187. FMonitor.DeleteCount(infoRec.User);
  188. lstThrds.Delete(I);
  189. Dispose(ptThrds);
  190. Break;
  191. end;
  192. end;
  193. finally
  194. FThrdsList.UnlockList;
  195. Dispose(infoRec);
  196. end;
  197. end;
  198. procedure TScCorrespondService.DoServerExecute(AThread: TIdPeerThread);
  199. var
  200. infoRec: PInfoRecd;
  201. strText: string;
  202. begin
  203. if AThread.Connection.Server.Active and not AThread.Terminated then
  204. begin
  205. strText := AThread.Connection.ReadLn(#13#10, 1000, 100);
  206. New(infoRec);
  207. FEncryptService.DeEncryptString(strText, infoRec);
  208. if infoRec.Action = 0 then {链接}
  209. begin
  210. if FMonitor.CanNotify(infoRec.User) then
  211. begin
  212. FMonitor.NotifyClientInfo(FClientInfoService, otAdd, infoRec);
  213. strText := FEncryptService.EncryptString('SUCCESS');
  214. AThread.Connection.WriteLn(strText);
  215. FMonitor.AddCount(infoRec.User);
  216. AddClientThrdsInfo(AThread, infoRec);
  217. end
  218. else
  219. begin
  220. strText := FEncryptService.EncryptString('ISFULL');
  221. AThread.Connection.WriteLn(strText);
  222. end;
  223. end
  224. else if infoRec.Action = 1 then {断开}
  225. begin
  226. FMonitor.NotifyClientInfo(FClientInfoService, otDelete, infoRec);
  227. FMonitor.DeleteCount(infoRec.User);
  228. DeleteClientthrdsInfo(AThread);
  229. end
  230. else if infoRec.Action = 9 then {检测}
  231. begin
  232. strText := FSofeDog.ReadData(StrToInt(infoRec.IP), infoRec.User);
  233. strText := FEncryptService.EncryptString(strText);
  234. AThread.Connection.WriteLn(strText);
  235. FMonitor.NotifyClientInfo(FClientInfoService, otModify, infoRec);
  236. end;
  237. Dispose(infoRec);
  238. end;
  239. end;
  240. procedure TScCorrespondService.InitMethods;
  241. begin
  242. // FIdTcpServer.OnConnect := DoServerConnect;
  243. FIdTcpServer.OnExecute := DoServerExecute;
  244. // FIdTcpServer.OnDisconnect := DoServerDisconnect;
  245. FIdTcpServer.OnException := DoServerException;
  246. end;
  247. function TScCorrespondService.Open: Boolean;
  248. begin
  249. Result := True;
  250. if FIdTcpServer.Active then Exit;
  251. FIdTcpServer.Bindings.Clear;
  252. FIdTcpServer.Threads.Clear;
  253. FIdTcpServer.DefaultPort := Port;
  254. try
  255. FIdTcpServer.Active := True;
  256. except
  257. Result := False;
  258. end;
  259. end;
  260. procedure TScCorrespondService.SetPort(const Value: Integer);
  261. begin
  262. FPersistent.Port := Value;
  263. end;
  264. procedure TScCorrespondService.SetMaxLinks(const AV0Count, AV1Count,
  265. AV2Count: Integer);
  266. begin
  267. FMonitor.SetMaxLinks(AV0Count, AV1Count, AV2Count);
  268. end;
  269. procedure TScCorrespondService.DeleteClientThrds;
  270. var
  271. I, iUser: Integer;
  272. strIP: string;
  273. lstThrds: TList;
  274. thrds: PThrdsRecd;
  275. begin
  276. iuser := FClientInfoService.CurUser;
  277. strIP := FClientInfoService.CurIP;
  278. lstThrds := FThrdsList.LockList;
  279. try
  280. for I := 0 to lstThrds.Count - 1 do
  281. begin
  282. thrds := lstThrds.List^[I];
  283. if SameText(thrds.IP, strIP) and (iUser = thrds.User) then
  284. begin
  285. if Assigned(thrds.Thread.Connection) then
  286. thrds.Thread.Connection.DisconnectSocket;
  287. FClientInfoService.DeleteCurRecord;
  288. FMonitor.DeleteCount(iUser);
  289. lstThrds.Delete(I);
  290. Dispose(thrds);
  291. Break;
  292. end;
  293. end;
  294. finally
  295. FThrdsList.UnlockList;
  296. end;
  297. end;
  298. procedure TScCorrespondService.AddClientThrdsInfo(AThread: TIdPeerThread;
  299. AInfo: PInfoRecd);
  300. var
  301. I: Integer;
  302. blFlag: Boolean;
  303. lstThrds: TList;
  304. ptThrds: PThrdsRecd;
  305. begin
  306. blFlag := False;
  307. lstThrds := FThrdsList.LockList;
  308. try
  309. for I := 0 to lstThrds.Count - 1 do
  310. begin
  311. ptThrds := lstThrds.List^[I];
  312. if AThread = ptThrds.Thread then
  313. begin
  314. blFlag := True;
  315. Break;
  316. end;
  317. end;
  318. if not blFlag then
  319. begin
  320. New(ptThrds);
  321. ptThrds.Thread := AThread;
  322. ptThrds.IP := AInfo.IP;
  323. ptThrds.User := AInfo.User;
  324. lstThrds.Add(ptThrds);
  325. end;
  326. finally
  327. FThrdsList.UnlockList;
  328. end;
  329. end;
  330. procedure TScCorrespondService.DeleteClientthrdsInfo(
  331. AThread: TIdPeerThread);
  332. var
  333. I: Integer;
  334. lstThrds: TList;
  335. ptThrds: PThrdsRecd;
  336. begin
  337. lstThrds := FThrdsList.LockList;
  338. try
  339. for I := 0 to lstThrds.Count - 1 do
  340. begin
  341. ptThrds := lstThrds.List^[I];
  342. if AThread = ptThrds.Thread then
  343. begin
  344. lstThrds.Delete(I);
  345. Dispose(ptThrds);
  346. Break;
  347. end;
  348. end;
  349. finally
  350. FThrdsList.UnlockList;
  351. end;
  352. end;
  353. procedure TScCorrespondService.ClearThrdsInfo;
  354. var
  355. I: Integer;
  356. lstThrds: TList;
  357. thrdsRec: PThrdsRecd;
  358. begin
  359. lstThrds := FThrdsList.LockList;
  360. try
  361. for I := 0 to lstThrds.Count - 1 do
  362. begin
  363. thrdsRec := lstThrds.List^[I];
  364. Dispose(thrdsRec);
  365. end;
  366. finally
  367. FThrdsList.UnlockList;
  368. end;
  369. FThrdsList.Clear;
  370. end;
  371. end.