zoukankan      html  css  js  c++  java
  • DIOCP之编写第一个应用程序(三)

    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同步临界区对象”,即数据更新界面,防假死

  • 相关阅读:
    C/C++
    不使用判断语句求一组数中的奇数/偶数个数
    heap(堆)
    One-Hot Encoding(独热编码)
    泰坦尼克号生存预测
    LaTeX 使用笔记
    python学习 —— seaborn、matplotlib、pandas、numpy package的混合使用
    Python 读取本地*.txt文件 替换 内容 并保存
    MySQL基本命令脚本
    MySQL简介
  • 原文地址:https://www.cnblogs.com/diocp/p/5860175.html
Copyright © 2011-2022 走看看