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

  • 相关阅读:
    POJ 3258 (NOIP2015 D2T1跳石头)
    POJ 3122 二分
    POJ 3104 二分
    POJ 1995 快速幂
    409. Longest Palindrome
    389. Find the Difference
    381. Insert Delete GetRandom O(1)
    380. Insert Delete GetRandom O(1)
    355. Design Twitter
    347. Top K Frequent Elements (sort map)
  • 原文地址:https://www.cnblogs.com/diocp/p/5860175.html
Copyright © 2011-2022 走看看