一个实例,如果客户端是TCP/IP是短连接的情况就没有必要了。

一、GlobVar.pas单元,定义应用系统全局数据类型及变量:

 unit GlobVar;

 interface

 uses System.SysUtils, System.Classes,IdTCPConnection,System.Generics.Collections,
Datasnap.DSTCPServerTransport,IdWinsock2,Data.DBXCommon,Datasnap.DBClient,
Datasnap.DSServer, Datasnap.DSCommonServer; type
pClientConns = ^TClientConns; // 客户连接 TClientConns = record
ClientId: integer;
Ip: string;
Port: string;
LoginTime: TDateTime;
end; const
gb_MaxConnNum = ;//每个进程最大连接数设置为1000 var
gb_ClientConnects: TDictionary<TIdTCPConnection, pClientConns>; // 客户端连接字典
gb_ConnnectCount:Integer=; //....

二、ServerContainer1.pas单元:

 uses GlobVar;
//...
procedure TServerContainer1.DSTCPServerTransport1Connect(Event: TDSTCPConnectEventObject);
var
p: pClientConns;
begin
try
if gb_ConnnectCount >= gb_MaxConnNum then
begin
LogInfo('已超过系统授权的客户连接数');
TIdTCPConnection(Event.Connection).Disconnect;
Exit;
end;
InterlockedIncrement(gb_ConnnectCount);
New(p);
if Assigned(p) then
begin
p^.ClientId := Event.Channel.ChannelInfo.Id;
p^.Ip := Event.Channel.ChannelInfo.ClientInfo.IpAddress;
p^.Port := Event.Channel.ChannelInfo.ClientInfo.ClientPort;
p^.LoginTime := Now;
gb_ClientConnects.Add(TIdTCPConnection(Event.Connection), p);
PostMessage(Application.SrvMainForm.Handle, WM_ADDUSER, wParam(p),lParam(TIdTCPConnection(Event.Connection)));
end;
except
Exit;
end;
end; procedure TServerContainer1.DSTCPServerTransport1Disconnect(Event: TDSTCPDisconnectEventObject);
var
p: pClientConns;
begin
try
if gb_ConnnectCount >= then
InterlockedDecrement(GlobalVar.gb_ConnnectCount);//GlobalVar.pas单元中定义了系统全局变量
p := gb_ClientConnects.Items[TIdTCPConnection(Event.Connection)];
if Assigned(p) then
begin
SendMessage(Application.SrvMainForm.Handle, WM_DELUSER, wParam(p), );
gb_ClientConnects.Remove(TIdTCPConnection(Event.Connection));
end;
except
Exit;
end;
end;

三、SrvMainForm.pas

 procedure TSrvMainForm.AddUser(var msg: TMessage);
var
p: pClientConns;
begin
try
lbl_MaxCount.Caption := IntToStr(gb_ConnnectCount);
p := pClientConns(msg.WParam);
if Assigned(p) then
begin
ClientDataSet1.Append;
ClientDataSet1.FieldByName('Id').AsInteger := p^.ClientId;
ClientDataSet1.FieldByName('Ip').AsString := p^.Ip;
ClientDataSet1.FieldByName('Port').AsString := p^.Port;
ClientDataSet1.FieldByName('LoginTime').AsDateTime := p^.LoginTime;
ClientDataSet1.FieldByName('Conn').AsInteger := msg.LParam;
ClientDataSet1.Post;
end;
except
on E: Exception do
begin
LogInfo('TSrvMainForm.AddUser---' + E.Message);
exit;
end;
end;
end; procedure TSrvMainForm.DelUser(var msg: TMessage);
var
p: pClientConns;
begin
try
lbl_MaxCount.Caption := IntToStr(gb_ConnnectCount);
p := pClientConns(msg.WParam);
if Assigned(p) then
begin
if ClientDataSet1.FindKey([p^.ClientId]) then //Id字段请设置索引
ClientDataSet1.Delete;
Dispose(p);
end;
except
on E: Exception do
begin
LogInfo('TSrvMainForm.DelUser---' + E.Message);
Exit;
end;
end;
end;

版权声明:本文为博主原创文章,未经博主允许不得转载。

最新文章

  1. 用Barcode生成条形码图片
  2. BZOJ 4548 小奇的糖果
  3. Bootstrap &lt;基础二十九&gt;面板(Panels)
  4. python面相对象进阶
  5. hdu1141(二进制数位,二分,打表)
  6. WOJ -1204
  7. Verilog学习笔记基本语法篇(十)&#183;&#183;&#183;&#183;&#183;&#183;&#183;&#183; 常用系统函数
  8. URAL 1517 Freedom of Choice(后缀数组,最长公共字串)
  9. oracle中事务处理
  10. MYsqli 绑定插入与查询实例
  11. Spring与Jdbc Demo
  12. Oprofile安装与使用探索
  13. 学习Selenium的历程
  14. Centos7.1 mini版安装后安装图形界面教程
  15. CS224d 单隐层全连接网络处理英文命名实体识别tensorflow
  16. 全网最详细的Windows系统里Oracle 11g R2 Database服务器端(64bit)的下载与安装(图文详解)
  17. CF#338D. GCD Table
  18. oracle存储过程-获取错误信息
  19. [Node.js]25. Level 5. Route params
  20. IOC容器基本原理

热门文章

  1. SQL中Len与DataLength区别
  2. iOS UIImage DownLoad图片的下载缓存全部在此
  3. Android 高级UI设计笔记13:Gallery(画廊控件)之 循环显示图像
  4. Java学习笔记——switch语句的参数类型
  5. (转)Git Gui for Windows的建库、克隆(clone)、上传(push)、下载(pull)、合并
  6. Sphinx 全文检索
  7. P2022 有趣的数
  8. Python之时间统计
  9. Page.ClientScript.RegisterStartupScript
  10. .NET DLL 保护措施应用实例(百度云分享工具)