Client

设计功能如下:

    1、建立与服务器连接

    2、请求连接时,加密密码,采用Base64编码

    3、定时发送心跳告诉服务器在线(长连接,用于接收推送信息)

    4、进行相关的数据处理与交互

第一步:创建一个VCL-Forms Application(创建一个标准VCL程序)

第二步:编写一个公共单元用于与Server通讯,因为客户端一般由多个窗体组成,所以需要一个公共连接类,不能放入窗体,不然窗体关闭,这个连接也会被关闭

以下单元是彩蛋的单元,我简化了,保留部分,用于学习,这个部分主要是向服务器发送请求

unit ClientIocpOper;

interface

uses
Classes,

diocp_coder_tcpClient,//与服务器进行通讯必要单元,当然你用indy来编写客户端就不需要此单元

SimpleMsgPack,//包处理单元

uDIOCPStreamCoder;//编码器与解码器的单元

/// <summary>
/// 请求登录
/// </summary>
/// <param name="AUserID">账号</param>
/// <param name="APaw">密码</param>
procedure CMD_Login(const AUserID, APaw: string);

/// <summary>

/// 初始化客户端使用的对象
/// </summary>
procedure IniClientObject;

/// <summary>
/// 销毁客户端创建的对象
/// </summary>
procedure UnIniClientObject;

var
CurUserID: string;//全局变量
CoderTcpClient: TDiocpCoderTcpClient;//全局通讯client
DiocpContext: TIocpCoderRemoteContext;//全局通讯DiocpContext
implementation

uses SysUtils;

var
CMDObject: TSimpleMsgPack;
CMDStream: TMemoryStream;

procedure SendCMDObject(pvCMDObject: TSimpleMsgPack);
var
lvCMDStream:TMemoryStream;
begin
lvCMDStream := TMemoryStream.Create;
try
pvCMDObject.EncodeToStream(lvCMDStream); // 加密消息
DiocpContext.WriteObject(lvCMDStream);
finally
lvCMDStream.Free;
end;
end;

 

 

procedure CMD_Login(const AUserID, APaw: string);
begin
// 连接
CoderTcpClient.open;
if DiocpContext.Active then Exit;
DiocpContext.Connect;
//sfLogger.logMessage('与服务器建立连接成功, 请进行登陆');
// 上线
if DiocpContext.Active then // 连接成功,请求登陆
begin
CMDObject.Clear;
CMDObject.ForcePathObject('cmdIndex').AsInteger := 11;
CMDObject.ForcePathObject('requestID').AsString := 'login';
CMDObject.ForcePathObject('user.id').AsString := AUserID;
CMDObject.ForcePathObject('user.paw').AsString := APaw;
SendCMDObject(CMDObject);
end;
end;

procedure CMD_KeepAlive;
begin
CMDObject.Clear;
CMDObject.ForcePathObject('cmdIndex').AsInteger := 0;
SendCMDObject(CMDObject);
end;

procedure IniClientObject;
begin
CoderTcpClient := TDiocpCoderTcpClient.Create(nil);

DiocpContext := TIocpCoderRemoteContext(CoderTcpClient.Add);
DiocpContext.RegisterCoderClass(TIOCPStreamDecoder, TIOCPStreamEncoder);

CMDObject := TSimpleMsgPack.Create;
CMDStream := TMemoryStream.Create;
end;

procedure UnIniClientObject;
begin
FreeAndNil(CMDObject);
CoderTcpClient.DisconnectAll;
CoderTcpClient.Free;
CMDStream.Free;
end;

initialization
IniClientObject;

finalization
UnIniClientObject;

end.

第四步:编写接收服务器数据,并更新客户端界面的组件

此部分要,在要建立起与tcpclient接收受数据的关联事件

procedure OnContextActionEx(AObject: TObject);

在窗体creat事件中,

DiocpContext.OnContextAction := OnContextActionEx; // 客户端上下文事件
DiocpContext.OnDisconnectedEvent := OnDisConnected;

然后就可以在OnContextActionEx处理来自服务器的数据,操作界面时注意“创建UI同步临界区对象”,即数据更新界面,防假死