DataSnap的如果网络断线,如何恢复?
timer代码很简单:
var adbsevertime :TDateTime;
begin
try
adbsevertime :=
ClientModule1.ServerMethods1Client.GetDbServerTime;
if adbsevertime <> 0 then
begin
gdbStatus := true;
TimerReconnet.Enable:=false;
end;
except
on E: Exception do
begin
TimerReconnet.Enable:=true;
end;
end;
end;
GetDbServerTime是dephi自动生成的客户端访问中间层的方法
网上找到三种方法:
http://www.cnblogs.com/yagzh2000/archive/2013/04/27/3046637.html
http://blog.csdn.net/sunstone/article/details/5023718
(http://blog.163.com/bin0315@126/blog/static/4066264220128414025829/
类似)
http://bbs.2ccc.com/topic.asp?topicid=396438
我每个测试一下,到时候结果通知大家。
我来说下这一天的成果:
因为自己很少用datasnap,然后网上对indy有偏见言辞,我抱着这个心态开始实验:
因为我用的是 datasnap rest 服务,也就是没有用tcp,用的是http,网上的资料对我来说初看没有用。xe2对于tcpconnection设置了心跳包属性,也对我来说无用。
因为用的是http,用后即关闭,所以心跳包是否有用,我也不清楚。
怎么办呢?最后我找到TIdHTTPWebBrokerBridge这个实例Fserver里面有个onconnect事件,可以用,于是就手写了事件照猫画虎把delphi2010的代码粘贴下来了,不知道是否用。
代码如下:
FServer := TIdHTTPWebBrokerBridge.Create(Self);
FServer.OnConnect:=ServerConnect;
FServer.OnDisconnect:= ServerDisConnect ;
实现代码:
procedure TForm1.ServerConnect(AContext: TIdContext);
var
Val: TCP_KeepAlive;
Ret: DWORD;
conne: tidtcpconnection;
aip, aport, ausername, apass: string;
begin
//验证
conne := TIdTCPConnection(AContext.Connection);
if conne <> nil then
begin
aip := conne.Socket.Binding.PeerIP;
aport := inttostr(conne.Socket.Binding.PeerPort);
// ausername := DSConnectEventObject.ConnectProperties[TDBXPropertyNames.UserName];
// apass := DSConnectEventObject.ConnectProperties[TDBXPropertyNames.Password];
// if (ausername <> 'jiangbin') and (apass <> '2010') then
// DSConnectEventObject.DbxConnection.Destroy
// else
// fr_main.memo1.Lines.add(aip + ':' + aport + ' 名称:' + ausername);
//心跳包代码
Val.OnOff := 1;
Val.KeepAliveTime := 5000;
Val.KeepAliveInterval := 3000;
WSAIoctl(conne.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4, @Val,
SizeOf(Val), nil, 0, @Ret, nil, nil);
end;
end;
procedure TForm1.ServerDisConnect(AContext: TIdContext);
var
conne: tidtcpconnection;
aip, aport, ausername, apass: string;
i: integer;
begin
//断开后清除连接IP及端口
conne := TIdTCPConnection(AContext.Connection);
if conne <> nil then
begin
aip := conne.Socket.Binding.PeerIP;
aport := IntToStr(conne.Socket.Binding.PeerPort);
end;
end;
但是不知道是否有用,待测。
另外,我在调试过程中,发现indy并不是想象的那么差,很完善
其实delphi事实是调用tidhttp 完成rest服务的,只是我这边有个问题,就是如果断线,调用异常,再次调用服务,就会出现服务器的index of bounds越界错误,(主要是构建http头,出现异常),这个应该是一个Indy bug吧,所以我准备临界来处理datasnap的中间层请求,保证异常后,不能同时再被访问,这样就可以了。
解决如果出现HTTP/1.1 403 Session has expired,datasnap不能重连功能,刚开始如果客户端正常连接中间层,然后中间层杀掉 ,客户端由于是用老的session去连接中间层,会被重新启动的中间层认为session过期。所以一直是返回raise,无限期不能重连。
解决方案,出现session错误时,把sessionid清空。
我发现问题跟tidhttp一毛钱关系没有,说明indy代码还是很不错的啊:)只是datasnap的代码未考虑异常。
解决如下:找到delphi源代码DSClientRest文件,复制到你的项目文件夹中,找到
procedure ExecuteCommand(ACommand: TDSRestCommand; const ARequestFilter, AAccept: string); overload;
把原先的1129行
ExecuteRequest(ACommand.Connection.HTTP, LURL, ACommand.RequestType, ACommand.Connection.LoginProperties.UserName, ACommand.Connection.LoginProperties.Password, ACommand.Parameters, ARequestFilter, AAccept,
LSessionID,
procedure
begin
ACommand.Connection.SessionExpired;
end,
procedure(ASessionID: string)
begin
if ASessionID <> '' then
ACommand.Connection.SessionID := ASessionID;
end);
改为:
try
ExecuteRequest(ACommand.Connection.HTTP, LURL, ACommand.RequestType, ACommand.Connection.LoginProperties.UserName, ACommand.Connection.LoginProperties.Password, ACommand.Parameters, ARequestFilter, AAccept,
LSessionID,
procedure
begin
ACommand.Connection.SessionExpired;
end,
procedure(ASessionID: string)
begin
if ASessionID <> '' then
ACommand.Connection.SessionID := ASessionID;
end);
except
on E:Exception do
begin
if Pos('Session has expired',E.Message)>0 then
begin
ACommand.Connection.SessionID:='';
end;
raise;
end;
end;
既可,这样,重连中间层可以实现了。
经过二个多月对于datasnap的一个项目学习,发现emb的人喜欢把程序员当做刚做程序的小白,所以代码很完善,让你很简单就建立了一个rest 服务(内部细节都由emb帮助你做好了)。但是他们处于实验室阶段,有时候没有考虑真实环境的差异,特别是一些异常未做处理。也就是说 有些坑需要你自己去填,但是填完后,发现datasnap还是不错的。:-)
http://bbs.2ccc.com/topic.asp?topicid=524327
DataSnap的如果网络断线,如何恢复?的更多相关文章
- 【12c】12c RMAN新特性之通过网络远程恢复数据库(RESTORE/Recover from Service)
[12c]12c RMAN新特性之通过网络远程恢复数据库(RESTORE/Recover from Service) 通过网络远程恢复数据库(Restore/Recover from Service) ...
- 在windows中安装OpenSSH,无密码登录,永远不断线
到这里下载最新安装包:https://github.com/PowerShell/Win32-OpenSSH/releases下载下来解压,然后用管理员打开服务器自带的PowerShell,运行下列命 ...
- RedisTemplate连接不释放、Redis断线不重连问题、Redis连接数高飙升
使用RedisTemplate操作Redis数据,但遇到网络断线后不会重新连接 毫无头绪 一顿捣鼓 最终解决 整理如下 帮助更多的人 1.起因 使用RedisTemplate 配置 开启了事务 ena ...
- iOS 网络框架编写总结
一,常用 1> 不错的处理接收到的网络图片数据的方法 id img= ISNSNULL(pic)?nil:[pic valueForKey:@"img"]; NSString ...
- MC3190终端配置冷启动自动恢复的方法
一. 网络配置的恢复 将当前文件夹下的注册表文件MC3190 Start Config.reg(见附件)复制到终端的Application文件夹内(可以通过数据线或ftp方式传送文件); 导出终端的网 ...
- mysql 恢复
一.备份的目的 做灾难恢复:对损坏的数据进行恢复和还原需求改变:因需求改变而需要把数据还原到改变以前测试:测试新功能是否可用 二.备份需要考虑的问题 可以容忍丢失多长时间的数据:恢复数据要在多长时间内 ...
- Oracle 12c Dataguard 数据库恢复
http://allthingsoracle.com/rolling-forward-a-physical-standby-database-using-the-recover-command/ 当主 ...
- mysql之6备份恢复
基本意义: 将数据另存到其他设备,以便于出现问题时恢复数据 为什么要备份: 灾难恢复:需求改变:测试 几个事先需要考虑的问题: 可以容忍丢失多长时间的数据?恢复要在多长时间内完成?是否 ...
- 【rabbitmq】RabbitMQ 集群与网络分区
网络分区(network partitions) 官网-网络分区 网络设备故障导致的网络分裂.比如,存在A\B\C\D\E五个节点,A\B处于同一子网,B\C\D处于另外一子网,中间通过交换机相连.若 ...
随机推荐
- Redis的持久化——AOF
上一篇博文给大家介绍了redis持久化的方式之一RDB,其中说到过RDB的缺陷是可能会导致数据丢失严重,所以redis的作者 由于强迫症又开发出了AOF来你补这一不足.好接下来我将为大家介绍AOF. ...
- 【离散化树状数组】Nordic Collegiate Programming Contest G.Galactic Collegiate Programming Contest
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; ; struct node { in ...
- Linux(14):集群架构进阶 --- CentOS 7
CentOS 7 CentOS 7 管理软件常用命令: vim /etc/selinux/config # 修改 SELINUX 开机自启动与否 setenforce 0 # 关闭 SELINUX g ...
- POSTMAN编写文档
第一步:创建文件夹: 同时创建全局变量: 第二步:创建分组文件夹: 第三步:添加请求: 类似正常调试,然后多了一步保存: 保存: 请求方式发生相应变化,同时颜色也发生变化,说明保存成功: ====== ...
- Mysql Binlog日志文件介绍
一.Binlog简介 官方文档参考 https://dev.mysql.com/doc/refman/5.5/en/binary-log.html Binlog(Binary Log) 指数据库的表创 ...
- GoldenDict词典下载安装
Debian/Ubuntu下载: sudo apt-get install goldendict 添加中文维基百科/维基词典: 选择[词典]->[词典来源]->[维基百科]->[添加 ...
- Java开发笔记(一百零一)通过加解锁避免资源冲突
前面介绍了如何通过线程同步来避免多线程并发的资源冲突问题,然而添加synchronized的方式只在简单场合够用,在一些高级场合就暴露出它的局限性,包括但不限于下列几点:1.synchronized必 ...
- 【Todo】已经打开的页面需要清掉的坑
下面是当前我浏览器里面打开的技术文章.需要清掉.一个坑一个坑地填吧. 微信文件传输里面也有几篇12.6号的<Akuna Capital电面面经><2016最流行的Java EE服务器 ...
- HDU 3342 Legal or Not (最短路 拓扑排序?)
Legal or Not Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- Go语言测试代码
第一次学go语言,测试代码 package main import "fmt" var age int; const sex = 0 func init() { fmt.Print ...