GroupClient.pas 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. unit GroupClient;
  2. interface
  3. uses
  4. superobject, GroupUtility, WebSocket2, WebSocketClient, Classes, Graphics,
  5. blcksock, SysUtils, DateUtils, GroupConfig, GroupProtocols, synautil,RealICQModel;
  6. type
  7. //表情类
  8. // TFace = class
  9. // private
  10. // FName: String;
  11. // FShortCut: String;
  12. // FFileName: String;
  13. // FMD5Code: String;
  14. // FCategory: String;
  15. // procedure SetFileName(const Value: String);
  16. // public
  17. //// constructor Create(AFileName, AShortCut, AName, AMD5Code: String; ACategory: String);
  18. //// procedure Assign(AFace: TFace);
  19. //// procedure SetFileName(Value: String);
  20. // published
  21. // property Name: String read FName write FName;
  22. // property ShortCut: String read FShortCut write FShortCut;
  23. // property FileName: String read FFileName write SetFileName;
  24. // property MD5Code: String read FMD5Code write FMD5Code;
  25. // property Category: String read FCategory write FCategory;
  26. // end;
  27. TGroupClient = class
  28. private
  29. FClient: TTestWebSocketClientConnection;
  30. FProtocol: TGroupProtocol;
  31. FLoginName: string;
  32. FConnected: Boolean;
  33. FGroupMonitor: TObject;
  34. FLastRecvMsg: ISuperObject;
  35. procedure GetMyGroups;
  36. procedure OnOpen(aSender: TWebSocketCustomConnection);
  37. procedure OnRead(aSender: TWebSocketCustomConnection; aFinal, aRes1, aRes2, aRes3: boolean; aCode: integer; aData: TMemoryStream);
  38. procedure OnClose(aSender: TWebSocketCustomConnection; aCloseCode: integer; aCloseReason: string; aClosedByPeer: boolean);
  39. public
  40. constructor Create();
  41. destructor Destroy; override;
  42. procedure Send(AData: string); overload;
  43. procedure Send(AProtocol: string; AData: ISuperObject); overload;
  44. procedure Ping;
  45. function Connect(ALoginName: string = ''): Boolean;
  46. procedure Disconnect;
  47. { TODO -olqq -c : 群组操作 2015/6/2 9:50:42 }
  48. procedure CreateTeam(ATeamName, ATeamCallBoard, ATeamIntro: string; ATeamMembers: TStringList; AIsTempTeam: Boolean);
  49. procedure RemoveTeam(ATeamID: string);
  50. procedure UpdateTeamInfo(ATeamID, AIntro, ANotice, AName: string; AAuth: Integer);
  51. procedure SearchTeam(ATeamID, AName, AIntro, ANotice: string; AMatchingType: TRealICQMatchingType; ASkip: Integer = 0; ALimit: Integer = 20);
  52. procedure AsynTeam(ATeamID: string);
  53. { TODO -olqq -c : 群成员操作 2015/6/2 10:03:30 }
  54. procedure AddTeamMembers(ATeamID: string; AMembersID, AManagersID: TStringList);
  55. procedure RemoveTeamMembers(ATeamID: string; AMembersID, AManagersID: TStringList);
  56. procedure SetAlias(ATeamID, AMemberID, Alias: string);
  57. function GetAlias(ATeamID, AMemberID: string): string;
  58. procedure InviteJoin(ATeamID,AOperatorID,AOperatorMsg: string;AMembers: TStringList);
  59. procedure JoinTeam(ATeamID, AMsg: string);
  60. procedure JoinTeamResponse(ATeamID, ALoginName, ATag: string; Accepted: Boolean);
  61. { TODO -olqq -c : 群消息 2015/6/2 10:11:20 }
  62. procedure SendTeamMessage(ATeamID, ASender, AMsg: string; AFont: TFont; AFaces: TStringList; Attachs: String);
  63. procedure GetOffineMessage;
  64. procedure MessageMisc(ATeamID: string);
  65. procedure MessageMiscMust(ATeamID: string);
  66. { TODO -olqq -c : 群图片 2015/6/3 9:39:26 }
  67. function UploadFile(Hash, FileName, ID, GroupID: string): Boolean;
  68. procedure SendFilesRequest(AGroupId, AUserId, FileName: string);
  69. property Connected: Boolean read FConnected write FConnected;
  70. end;
  71. implementation
  72. uses
  73. IdHTTP, LoggerImport, GroupMonitor, xFonts, {MainFrm,} IdMultipartFormData,
  74. HTTPApp, RealICQClient;
  75. const
  76. UPLOAD_URL: string = 'http://%s:%d/file/upload';
  77. { TGroupClient }
  78. procedure TGroupClient.CreateTeam(ATeamName, ATeamCallBoard, ATeamIntro: String;
  79. ATeamMembers: TStringList; AIsTempTeam: Boolean);
  80. var
  81. createGroup:String;
  82. jo, AData: ISuperObject;
  83. AMemebers: TSuperArray;
  84. iLoop: Integer;
  85. begin
  86. jo := SO(GROUP_CREATE_JSON);
  87. jo.S['id'] := '';
  88. jo.S['group.name'] := Trim(ATeamName);
  89. jo.I['group.type'] := 0;
  90. jo.S['group.creator'] := FLoginName;
  91. jo.S['group.intro'] := Trim(ATeamIntro);
  92. jo.S['group.notice'] := Trim(ATeamCallBoard);
  93. AMemebers := jo.A['group.members'];
  94. for iLoop := 0 to ATeamMembers.Count - 1 do
  95. AMemebers.S[iloop] := ATeamMembers[iLoop];
  96. Send(GROUP_CREATE_REQUEST, jo);
  97. end;
  98. procedure TGroupClient.RemoveTeam(ATeamID: String);
  99. var
  100. jo: ISuperObject;
  101. begin
  102. jo := SO('{"id":"", "group":{"id":""}}');
  103. jo.S['group.id'] := ATeamID;
  104. Send(GROUP_DEL_REQUEST, jo);
  105. end;
  106. procedure TGroupClient.UpdateTeamInfo(ATeamID, AIntro, ANotice, AName: string;
  107. AAuth: Integer);
  108. var
  109. jo: ISuperObject;
  110. begin
  111. jo := SO('{"id":"", "group":{"id":"","intro":"","notice":"","name":"","auth":0}}');
  112. jo.S['group.id'] := ATeamID;
  113. jo.S['group.intro'] := AIntro;
  114. jo.S['group.notice'] := ANotice;
  115. jo.S['group.name'] := AName;
  116. jo.I['group.auth'] := AAuth;
  117. Send(GROUP_UPDATE_REQUEST, jo);
  118. end;
  119. procedure TGroupClient.AsynTeam(ATeamID: String);
  120. var
  121. jo: ISuperObject;
  122. begin
  123. jo := SO('{"id":"","group":{"id":""}}');
  124. jo.S['group.id'] := ATeamID;
  125. Send(GROUP_GET_REQUEST, jo);
  126. end;
  127. procedure TGroupClient.SearchTeam(ATeamID, AName, AIntro, ANotice: string;
  128. AMatchingType: TRealICQMatchingType; ASkip: Integer = 0; ALimit: Integer = 20);
  129. var
  130. jo: ISuperObject;
  131. SearchGroup: String;
  132. begin
  133. jo := SO('{"id":"","group":{"id":"","intro":"","name":"","notice":""},"skip":0,"limit":0}');
  134. jo.S['group.id'] := ATeamID;
  135. if AIntro <> '' then
  136. begin
  137. if AMatchingType = mtLikeSearch then
  138. jo.S['group.intro'] := '*' + AIntro
  139. else
  140. jo.S['group.intro'] := AIntro;
  141. end;
  142. if AName <> '' then
  143. begin
  144. if AMatchingType = mtLikeSearch then
  145. jo.S['group.name'] := '*' + AName
  146. else
  147. jo.S['group.name'] := AName;
  148. end;
  149. if ANotice <> '' then
  150. begin
  151. if AMatchingType = mtLikeSearch then
  152. jo.S['group.notice'] := '*' + ANotice
  153. else
  154. jo.S['group.notice'] := ANotice;
  155. end;
  156. jo.I['skip'] := ASkip;
  157. jo.I['limit'] := ALimit;
  158. Send(GROUP_QUERY_REQUEST, jo);
  159. end;
  160. procedure TGroupClient.AddTeamMembers(ATeamID: string; AMembersID,
  161. AManagersID: TStringList);
  162. var
  163. jo :ISuperObject;
  164. ja,ja1: TSuperArray;
  165. iLoop : Integer;
  166. begin
  167. jo := SO('{"id":"", "group":{"id":"","members":[],"managers": []}}');
  168. jo.S['group.id'] := ATeamID;
  169. ja := jo.A['group.members'];
  170. if (AMembersID <> nil) then
  171. for iLoop := 0 to AMembersID.Count - 1 do
  172. ja.S[iloop] := AMembersID[iLoop];
  173. ja1 := jo.A['group.managers'];
  174. if (AManagersID <> nil) then
  175. for iLoop := 0 to AManagersID.Count - 1 do
  176. ja1.S[iloop] := AManagersID[iLoop];
  177. Send(MEMBER_ADD_REQUEST, jo);
  178. end;
  179. procedure TGroupClient.RemoveTeamMembers(ATeamID: string; AMembersID,
  180. AManagersID: TStringList);
  181. var
  182. jo :ISuperObject;
  183. ja,ja1: TSuperArray;
  184. iLoop : Integer;
  185. begin
  186. jo := SO('{"id":"", "group":{"id":"","members":[],"managers": []}}');
  187. jo.S['group.id'] := ATeamID;
  188. if AMembersID <> nil then
  189. begin
  190. ja := jo.A['group.members'];
  191. for iLoop := 0 to AMembersID.Count - 1 do
  192. ja.S[iloop] := AMembersID[iLoop];
  193. end;
  194. if AManagersID <> nil then
  195. begin
  196. ja1 := jo.A['group.managers'];
  197. for iLoop := 0 to AManagersID.Count - 1 do
  198. ja1.S[iloop] := AManagersID[iLoop];
  199. end;
  200. Send(MEMBER_DEL_REQUEST, jo);
  201. end;
  202. procedure TGroupClient.SetAlias(ATeamID, AMemberID, Alias: string);
  203. var
  204. jo,jo1: ISuperObject;
  205. ja: TSuperArray;
  206. begin
  207. jo := SO('{"id":"","group":{"id":"","members":[]}}');
  208. jo1:= SO('{"id":"","alias":""}');
  209. jo.S['group.id']:= ATeamID;
  210. jo1.S['id'] := AMemberID;
  211. jo1.S['alias'] := Alias;
  212. ja := jo.A['group.members'];
  213. ja.Add(jo1);
  214. Send(MEMBER_UPDATE_REQUEST, jo);
  215. end;
  216. procedure TGroupClient.InviteJoin(ATeamID, AOperatorID, AOperatorMsg: string;
  217. AMembers: TStringList);
  218. var
  219. jo: ISuperObject;
  220. ja: TSuperArray;
  221. ILoop : Integer;
  222. begin
  223. jo := SO('{"id":"","group":{"id":"","members":[], "operator":{"id":"","msg":""}}}');
  224. jo.S['group.id']:= ATeamID;
  225. jo.S['group.operator.id']:= AOperatorID;
  226. jo.S['group.operator.msg']:= AOperatorMsg;
  227. ja := jo.A['group.members'];
  228. for iLoop := 0 to AMembers.Count - 1 do
  229. ja.S[iloop] := AMembers[iLoop];
  230. Send(INVITE_REQUEST, jo);
  231. end;
  232. procedure TGroupClient.JoinTeam(ATeamID, AMsg: string);
  233. var
  234. jo: ISuperObject;
  235. begin
  236. jo := SO('{"group":{"id":"","apply":{"uid":"","msg":""}}}');
  237. jo.S['group.id'] := ATeamID;
  238. jo.S['group.apply.msg'] := AMsg;
  239. jo.S['group.apply.uid'] := FLoginName;
  240. Send(MEMBER_APPLY_REQUEST, jo);
  241. end;
  242. procedure TGroupClient.JoinTeamResponse(ATeamID, ALoginName, ATag: string; Accepted: Boolean);
  243. var
  244. jo: ISuperObject;
  245. begin
  246. jo := SO('{"id":"","group":{"id":"","apply":{"uid":""},"reply":{"uid":"", "ret":0}}}');
  247. jo.S['group.id'] := ATeamID;
  248. jo.S['group.apply.uid'] := ALoginName;
  249. jo.S['group.reply.uid'] := FLoginName;
  250. jo.S['group.reply.msg'] := ATag;
  251. if Accepted then
  252. jo.I['group.reply.ret'] := 1
  253. else
  254. jo.I['group.reply.ret'] := 0;
  255. Send(MEMBER_REPLY_REQUEST, jo);
  256. end;
  257. procedure TGroupClient.SendTeamMessage(ATeamID, ASender, AMsg: String;
  258. AFont: TFont; AFaces: TStringList; Attachs: String);
  259. var
  260. jo, jofile, joNotify, joFont: ISuperObject;
  261. ja, jaHashs: TSuperArray;
  262. iLoop : Integer;
  263. sendstr: String;
  264. AFace: TFace;
  265. IMG_TAG, ATT_TAG: string;
  266. begin
  267. if Attachs <> '' then
  268. ATT_TAG := ',"attach":[]';
  269. if AFaces.Count > 0 then
  270. IMG_TAG := ',"img":[]';
  271. jo := SO('{"group":{"id":""},"content":""}');
  272. // if (Attachs = '') and (AFaces.Count = 0) then
  273. // jo := SO('{"group":{"id":""},"txt":""}')
  274. // else if (Attachs = '') and (AFaces.Count > 0) then
  275. // jo := SO('{"grou p":{"id":""},"txt":"","img":[]}')
  276. // else if (Attachs <> '') and (AFaces.Count = 0) then
  277. // jo := SO('{"group":{"id":""},"txt":"","attach":[]}')
  278. // else
  279. // jo := SO('{"group":{"id":""},"txt":"","img":[],"attach":[]}');
  280. jo.S['group.id'] := ATeamID;
  281. jo.S['content'] := AMsg;
  282. jo.I['isDes'] := 0;
  283. jo.I['msgType'] := 1;
  284. jo.I['fromClient'] := 0;
  285. jo.I['networkType'] := 0;
  286. joFont := FontToJson(AFont);
  287. if joFont <> nil then
  288. jo.O['style'] := joFont;
  289. if Attachs <> '' then
  290. begin
  291. jo.A['attach'].S[0] := Attachs;
  292. end;
  293. if AFaces.Count > 0 then
  294. begin
  295. joNotify := SO('{"group":{"id":""},"hashs":[]}');
  296. joNotify.S['group.id'] := ATeamID;
  297. jaHashs := joNotify.A['hashs'];
  298. for iLoop := 0 to AFaces.Count - 1 do
  299. begin
  300. AFace := AFaces.Objects[iLoop] as TFace;
  301. jofile := SO();
  302. jofile.S['file'] := ExtractFileName(AFace.FileName);
  303. jofile.S['hash'] := LowerCase(AFace.MD5Code);
  304. // jo.A['img'].Add(jofile);
  305. if UploadFile(jofile.S['hash'], jofile.S['file'], '', ATeamID) then
  306. jaHashs.Add(jofile);
  307. end;
  308. Send(MESSAGE_SAY_REQUEST, jo);
  309. if jaHashs.Length > 0 then
  310. Send(FILE_UPLOADED_REQUEST, joNotify);
  311. Exit;
  312. end;
  313. Send(MESSAGE_SAY_REQUEST, jo);
  314. MessageMisc(ATeamID);
  315. end;
  316. procedure TGroupClient.MessageMisc(ATeamID: string);
  317. var
  318. ATick: Cardinal;
  319. begin
  320. ATick := FLastRecvMsg.I[ATeamID];
  321. if (ATick <> 0) and (GetTick - ATick < 5000) then
  322. Exit;
  323. MessageMiscMust(ATeamID);
  324. FLastRecvMsg.I[ATeamID] := GetTick;
  325. end;
  326. procedure TGroupClient.MessageMiscMust(ATeamID: string);
  327. var
  328. jo: ISuperObject;
  329. begin
  330. jo := SO('{"id":"","msg":[], ev:[]}');
  331. jo.A['msg'].S[0] := ATeamID;
  332. Send(MARK_MK_REQUEST, jo);
  333. end;
  334. function GetSID(AResponseStr: string): string;
  335. var
  336. ACode: Byte;
  337. AStream: TStringStream;
  338. Len: Int64;
  339. begin
  340. Result := '';
  341. AStream := TStringStream.Create(AResponseStr);
  342. try
  343. AStream.Position :=1;
  344. Len := 0;
  345. AStream.Read(ACode, 1);
  346. while ACode <> $FF do
  347. begin
  348. Len := Len * 10;
  349. Inc(Len, ACode);
  350. AStream.Read(ACode, 1);
  351. end;
  352. //Code
  353. AStream.Read(ACode, 1);
  354. Result := AStream.ReadString(AStream.Size - AStream.Position);
  355. finally
  356. FreeAndNil(AStream);
  357. end;
  358. end;
  359. //{"socket":{"id":"639d9b0204f343a2acd5dfc3bf38b7f0","type":"mix","port":6714,"ver":"3.2.0","ip":"192.168.1.43","onlines":0},"storage":{"host":"127.0.0.1","port":6713}}
  360. function GatewayResponse(AJsonStr: string): Boolean;
  361. var
  362. jo: ISuperObject;
  363. config: TGroupConfig;
  364. begin
  365. Result := False;
  366. jo := SO(AJsonStr);
  367. if jo = nil then
  368. Exit;
  369. config := TGroupConfig.GetConfig;
  370. config.IP := jo.S['socket.host'];
  371. config.Port := jo.I['socket.port'];
  372. Success(Format('群组服务器:%s:%d', [config.IP, config.Port]), 'GatewayResponse');
  373. config.ImageIP := jo.S['storage.host'];
  374. config.ImagePort := jo.I['storage.port'];
  375. Result := True;
  376. end;
  377. function TGroupClient.Connect(ALoginName: string = ''): Boolean;
  378. var
  379. AIdHttp:TIdHTTP;
  380. ResponeStr,sid: string;
  381. config: TGroupConfig;
  382. AURL: string;
  383. begin
  384. if ALoginName <> '' then
  385. FLoginName := ALoginName;
  386. if Trim(FLoginName) = '' then
  387. Exit;
  388. AIdHttp:= TIdHTTP.Create(nil);
  389. try
  390. config := TGroupConfig.GetConfig;
  391. if config.GatewayEnable then
  392. begin
  393. config.RandomGatewayServer;
  394. AURL := Format(GATEWAY_URL, [config.GatewayIP, config.GatewayPort]);
  395. ResponeStr := AIdHttp.Get(AURL);
  396. if not GatewayResponse(ResponeStr) then
  397. Exit;
  398. end;
  399. AURL := Format(SHAKEHANDS_STEP1, [config.IP, config.Port, HTTPEncode(AnsiToUtf8(FLoginName)), (DateTimeToUnix(Now) - 8*60*60) * 1000]);
  400. ResponeStr := AIdHttp.get(AURL);
  401. ResponeStr := GetSID(ResponeStr);
  402. sid := SO(ResponeStr).S['sid'];
  403. AURL := Format(SHAKEHANDS_STEP2, [config.IP, config.Port, HTTPEncode(AnsiToUtf8(FLoginName)), (DateTimeToUnix(Now) - 8*60*60) * 1000, sid]);
  404. ResponeStr := AIdHttp.get(AURL);
  405. if FClient <> nil then
  406. FreeAndNil(FClient);
  407. AURL := Format(WEBSOCKET_URL, [HTTPEncode(AnsiToUtf8(FLoginName)), sid]);
  408. FClient := TTestWebSocketClientConnection.Create(config.IP, IntToStr(config.Port), AURL, '-', 'ws');
  409. FClient.OnRead := OnRead;
  410. FClient.OnClose := OnClose;
  411. FClient.OnOpen := OnOpen;
  412. FClient.Start;
  413. except
  414. on E: Exception do
  415. begin
  416. Freeandnil(AIdHttp);
  417. Error(E.Message, 'TGroupClient.Connect');
  418. Exit;
  419. end;
  420. end;
  421. Freeandnil(AIdHttp);
  422. end;
  423. function TGroupClient.UploadFile(Hash, FileName, ID, GroupID: String): Boolean;
  424. var
  425. AHttp: TIdHttp;
  426. MutPartForm: TIdMultiPartFormDataStream;
  427. Ret:TStringStream;
  428. response,UpUrl: String;
  429. jo,t,jofile: ISuperObject;
  430. SendStr: String;
  431. config: TGroupConfig;
  432. begin
  433. Result := False;
  434. config := TGroupConfig.GetConfig;
  435. UpUrl := Format(UPLOAD_URL, [config.ImageIP, config.ImagePort]);
  436. AHttp := Tidhttp.Create(nil);
  437. AHttp.Request.ContentType:='multipart/form-data';
  438. AHttp.HandleRedirects := true;
  439. AHttp.AllowCookies := true;
  440. MutPartForm := TIdMultiPartFormDataStream.Create;
  441. MutPartForm.AddFile('file1', TRealICQClient.GetReceivedFaceDir+FileName,'');
  442. try
  443. response := AHttp.Post(UpUrl, MutPartForm);
  444. finally
  445. MutPartForm.Free;
  446. AHttp.Free;
  447. end;
  448. if response = 'ok' then
  449. Result := True;
  450. end;
  451. constructor TGroupClient.Create;
  452. begin
  453. FGroupMonitor := TGroupMonitor.Create;
  454. FProtocol := TGroupProtocol.Create(Self);
  455. FLastRecvMsg := SO('{}');
  456. end;
  457. destructor TGroupClient.Destroy;
  458. var
  459. PInt: PInteger;
  460. begin
  461. FreeAndNil(FGroupMonitor);
  462. if FClient <> nil then
  463. FreeAndNil(FClient);
  464. FLastRecvMsg := nil;
  465. FProtocol.Free;
  466. inherited;
  467. end;
  468. procedure TGroupClient.Disconnect;
  469. begin
  470. (FGroupMonitor as TGroupMonitor).Stop;
  471. (FGroupMonitor as TGroupMonitor).KeepAlive := False;
  472. if FConnected then
  473. begin
  474. FClient.Close(wsCloseNormal, 'goodbye');
  475. FConnected := False;
  476. end;
  477. end;
  478. function TGroupClient.GetAlias(ATeamID, AMemberID: string): string;
  479. begin
  480. end;
  481. procedure TGroupClient.GetMyGroups;
  482. var
  483. jo: ISuperObject;
  484. begin
  485. jo := SO('{}');
  486. jo.S['user'] := FLoginName;
  487. Send(USER_LI_REQUEST, jo);
  488. end;
  489. procedure TGroupClient.GetOffineMessage;
  490. var
  491. jo: ISuperObject;
  492. begin
  493. // jo := SO('{}');
  494. // jo.S['uid'] := FLoginName;
  495. // Send(MESSAGE_OFFLINE_REQUEST, jo);
  496. end;
  497. procedure TGroupClient.OnClose(aSender: TWebSocketCustomConnection;
  498. aCloseCode: integer; aCloseReason: string; aClosedByPeer: boolean);
  499. begin
  500. FConnected := False;
  501. FClient := nil;
  502. (FGroupMonitor as TGroupMonitor).Stop;
  503. if (aClosedByPeer) or (aCloseCode <> 1000) then
  504. begin
  505. Error(Format('异常断开. Code:%d;Reson:%s;ClolsedByPeer:%s;', [aCloseCode, aCloseReason, BoolToStr(aClosedByPeer)]), 'TGroupClient.OnClose');
  506. end
  507. else
  508. Success(Format('正常断开. Code:%d;Reson:%s;ClolsedByPeer:%s;', [aCloseCode, aCloseReason, BoolToStr(aClosedByPeer)]), 'TGroupClient.OnClose');
  509. end;
  510. procedure TGroupClient.OnOpen(aSender: TWebSocketCustomConnection);
  511. begin
  512. Success(FLoginName, 'OnOpen');
  513. FConnected := True;
  514. FClient.SendText('2probe');
  515. (FGroupMonitor as TGroupMonitor).Start(Self);
  516. (FGroupMonitor as TGroupMonitor).KeepAlive := True;
  517. // GetMyGroups;
  518. end;
  519. procedure TGroupClient.OnRead(aSender: TWebSocketCustomConnection; aFinal,
  520. aRes1, aRes2, aRes3: boolean; aCode: integer; aData: TMemoryStream);
  521. var
  522. s,Recvdata: string;
  523. c: TTestWebSocketClientConnection;
  524. begin
  525. try
  526. (FGroupMonitor as TGroupMonitor).ReflashLastTime;
  527. c := TTestWebSocketClientConnection(aSender);
  528. s := ReadStrFromStream(c.ReadStream, c.ReadStream.size{min(c.ReadStream.size, 10 * 1024)});
  529. if (c.ReadCode = wsCodeText) then
  530. Recvdata := utf8toansi(s)//CharsetConversion(s, UTF_8, GetCurCP)
  531. else
  532. Recvdata := s;
  533. if SameText(Recvdata, '3probe') then
  534. begin
  535. FClient.SendText('5');
  536. GetMyGroups;
  537. Exit;
  538. end;
  539. Success(Recvdata, 'TGroupClient.OnRead');
  540. if (Length(Recvdata) < 4) or (FProtocol = nil) then
  541. Exit;
  542. FProtocol.Proccess(Recvdata);
  543. except
  544. on E: Exception do
  545. Error(E.Message, 'TGroupClient.OnRead('+Recvdata+')');
  546. end;
  547. end;
  548. procedure TGroupClient.Ping;
  549. begin
  550. if (FClient <> nil) and (not FClient.Closed) then
  551. FClient.SendText('2');
  552. end;
  553. procedure TGroupClient.Send(AProtocol: string; AData: ISuperObject);
  554. var
  555. AJo: ISuperObject;
  556. begin
  557. AJo := SO('[]');
  558. AJo.AsArray.S[0] := AProtocol;
  559. AJo.AsArray.O[1] := AData;
  560. Send('42' + AJo.Asjson);
  561. end;
  562. procedure TGroupClient.Send(AData: string);
  563. begin
  564. try
  565. if (FClient <> nil) and (not FClient.Closed) then
  566. FClient.SendText(AnsiToUTF8(AData));
  567. Success(AData, 'TGroupClient.Send');
  568. except
  569. on E: Exception do
  570. begin
  571. Error(E.Message, 'TGroupClient.Send('+AData+')');
  572. end;
  573. end;
  574. end;
  575. procedure TGroupClient.SendFilesRequest(AGroupId, AUserId, FileName: String);
  576. begin
  577. end;
  578. end.