zoukankan      html  css  js  c++  java
  • DataSnap 2009 客户端扩展

    DataSnap 2009的客户端采用了原始的TClientSocket组件实现了通讯层 即简单效率也不错

    但是如果我们想要设置连接超时怎么办?想要设置代理服务器又该怎么办呢?能不能利用我们常用的网络控件(indy ics synapse...)来替代呢?

    在这里我基于synapse控件实现了一个自己的DataSnap客户端驱动

    注: synapase是一套比较不错的开源的第三方控件 这里我们要使用它的TCP控件来扩展支持代理服务器的使用

    synapse 官方网址 http://www.synapse.ararat.cz/doku.php

    synapse svn地址 https://synalist.svn.sourceforge.net/svnroot/synalist/trunk

    首先我们必须注册一个新的驱动

    // 客户端驱动定义
    TCfSynaTCPDatasnapDriver
    = class(TDBXClientDriver)
    protected
    function CreateChannel: TDbxChannel; override;
    public
    constructor Create(DriverDef: TDBXDriverDef); override;
    end;

    // 驱动名称
    const SDriverName = 'CfSynaTCPDataSnap';

    // 单元初始化时注册驱动
    initialization
    TDBXDriverRegistry.RegisterDriverClass(SDriverName, TCfSynaTCPDatasnapDriver);

    TDBXClientDriver的CreateChannel方法默认创建的是TDBXSocketChannel 所以我们要在我们的类中覆盖它并且创建一个自己的Channel

    // Synapse 实现的TCP通道
    TCfSynaTCPChannel
    = class(TDBXChannel)
    private
    FTcpClient: TTCPBlockSocket; // Synapse的TCP控件
    protected
    function GetChannelInfo: TDBXChannelInfo; override;
    public
    destructor Destroy; override;
    procedure Open; override;
    procedure Close; override;
    function Read(const Buffer: TBytes; const Offset: Integer; const Count: Integer): Integer; override;
    function Write(const Buffer: TBytes; const Offset: Integer; const Count: Integer): Integer; override;
    end;

    那么我们如何读取SQLConnection设置的参数值呢 比如服务器信息 代理服务器信息之类的设置呢

    为了减少代码量我在这里直接继承TDBXDatasnapProperties类实现了TCfSynaTCPDatasnapProperties类来设置代理服务器信息

    // 包含代理服务器配置的属性类
    TCfSynaTCPDatasnapProperties
    = class(TDBXDatasnapProperties)
    strict
    private
    function GetProxyIP: string;
    function GetProxyPort: string;
    function GetProxyUsername: string;
    function GetProxyPassword: string;
    function GetProxyTimeout: Integer;
    function GetProxyType: TProxyType;
    procedure SetProxyIP(const Value: string);
    procedure SetProxyPort(const Value: string);
    procedure SetProxyUsername(const Value: string);
    procedure SetProxyPassword(const Value: string);
    procedure SetProxyTimeout(const Value: Integer);
    procedure SetProxyType(const Value: TProxyType);
    published
    property ProxyIP: string read GetProxyIP write SetProxyIP;
    property ProxyPort: string read GetProxyPort write SetProxyPort;
    property ProxyUsername: string read GetProxyUsername write SetProxyUsername;
    property ProxyPassword: string read GetProxyPassword write SetProxyPassword;
    property ProxyTimeout: Integer read GetProxyTimeout write SetProxyTimeout;
    property ProxyType: TProxyType read GetProxyType write SetProxyType;
    end;

    然后通过TCfSynaTCPDatasnapDriver的构造函数传递

    复制DbxDatasnap单元TDBXDatasnapDriver的代码 把TDBXDatasnapProperties改成TCfSynaTCPDatasnapProperties

    这样我们就可以根据参数的配置来连接服务器

    procedure TCfSynaTCPChannel.Open;
    begin
    Close;
    if FTcpClient = nil then
    FTcpClient :
    = TTCPBlockSocket.Create;
    with TCfSynaTCPDatasnapProperties(DbxProperties) do
    begin
    if ProxyIP <> '' then
    begin
    case ProxyType of
    ptSocks4:
    FTcpClient.SocksType :
    = ST_Socks4;
    ptSocks5:
    FTcpClient.SocksType :
    = ST_Socks5;
    end;
    case ProxyType of
    ptSocks4, ptSocks5:
    begin
    FTcpClient.SocksIP :
    = ProxyIP;
    FTcpClient.SocksPort :
    = ProxyPort;
    FTcpClient.SocksUsername :
    = ProxyUsername;
    FTcpClient.SocksPassword :
    = ProxyPassword;
    FTcpClient.SocksTimeout :
    = ProxyTimeout;
    end;
    ptHTTP:
    begin
    FTcpClient.HTTPTunnelIP :
    = ProxyIP;
    FTcpClient.HTTPTunnelPort :
    = ProxyPort;
    FTcpClient.HTTPTunnelUser :
    = ProxyUsername;
    FTcpClient.HTTPTunnelPass :
    = ProxyPassword;
    FTcpClient.HTTPTunnelTimeout :
    = ProxyTimeout;
    end;
    end;
    end;
    FTcpClient.Connect(HostName, IntToStr(Port));
    end;
    FChannelInfo :
    = TDBXSocketChannelInfo.Create(0, FTcpClient.GetLocalSinIP);
    end;

    调用代码示例

    with DM.SQLConnection do
    begin
    Close;
    Params.Values[TCfSynaTCPNames.ProxyType] :
    = IntToStr(Integer(ptHTTP));
    Params.Values[TCfSynaTCPNames.ProxyIP] :
    = 'localhost';
    Params.Values[TCfSynaTCPNames.ProxyPort] :
    = '80';
    Params.Values[TCfSynaTCPNames.ProxyUsername] :
    = 'abc';
    Params.Values[TCfSynaTCPNames.ProxyPassword] :
    = '123';
    Params.Values[TDBXPropertyNames.HostName] :
    = 'localhost';
    Params.Values[TDBXPropertyNames.Port] :
    = '1217';
    try
    Open;
    except
    end
    end;

    单元实现完整代码 CfSynaTCPChannel.rar

    注: 该单元可以直接引用也可以新建个包安装 最好在Register函数中调用InstallSynaDriver

    否则IDE中SQLConnection控件的Driver设置成CfSynaTCPDataSnap下次打开的时候可能会报错

  • 相关阅读:
    Spring学习-- AOP入门动态代理
    Spring学习--泛型依赖注入
    Spring学习--通过注解配置 Bean (三)
    Spring学习--通过注解配置 Bean (二)
    Spring学习--通过注解配置 Bean (一)
    十 字符串处理
    九 Shell中的数组
    八使用Shell函数
    七 循环结构
    六、流程控制语句
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/2187835.html
Copyright © 2011-2022 走看看