本文共 4054 字,大约阅读时间需要 13 分钟。
DataSnap 2009的客户端采用了原始的TClientSocket组件实现了通讯层 即简单效率也不错
但是如果我们想要设置连接超时怎么办?想要设置代理服务器又该怎么办呢?能不能利用我们常用的网络控件(indy ics synapse...)来替代呢?
在这里我基于synapse控件实现了一个自己的DataSnap客户端驱动
注: synapase是一套比较不错的开源的第三方控件 这里我们要使用它的TCP控件来扩展支持代理服务器的使用
synapse 官方网址
synapse svn地址
首先我们必须注册一个新的驱动
// 客户端驱动定义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 ; 单元实现完整代码
注: 该单元可以直接引用也可以新建个包安装 最好在Register函数中调用InstallSynaDriver
否则IDE中SQLConnection控件的Driver设置成CfSynaTCPDataSnap下次打开的时候可能会报错
转载地址:http://rvagl.baihongyu.com/