Delphi中SOAP或IndyHttp可否实现异步回调? ( 积分: 200 )

  • 主题发起人 主题发起人 VictorWoo
  • 开始时间 开始时间
V

VictorWoo

Unregistered / Unconfirmed
GUEST, unregistred user!
基本需求:
Client在内网,Server在公网。当Client连上Server后,Server由用户操作,可随时向Client发命令。Client *即*时* 执行完后返回结果给Server,Server处理并显示执行结果。

难点:
由于SOAP或者是TIdHTTP,都必须是Client主动连接Server,而连上以后,业务请求全部是倒过来由Server对Client发。

以上过程希望通过SOAP或indy HTTP Client/Server实现,不知可否?

还有一个半成品的思路:

Client在一个心跳周期中问Server:我需要做什么?然后阻塞
Server不马上回答,直到用户指定了某操作了以后,才回答:你要做XXX。(这一步是否可以用线程中加WaitForSingleObject?)
Client收到这个回复,执行XXX操作,把结果送回服务器,并要求下一轮:“我需要做什么?”
若Server的回复超过了1个心跳周期,Client重复上述过程。Server也使用定时器清除过期的请求。

当然如果SOAP或indy http可以做到Server随时调Client中的函数,上面的所有机制都不用了。不知道能否满足上述需求?
 
一个idhttp的草稿(伪代码),大家评价一下是否可行?

客户端:
thread.OnExecute()
{
while true
{
idhttp.get('http://ip/?packetType=心跳包&cmd=我要做啥',60秒);
}
}
这样既有心跳包的功能,又有领取命令的功能,频率很低,才60秒一次


服务端:
idhttpsrvr.OnGet()
{
读取数据;
waitforsingleobject(mutex.Handle,60);
发送数据(Data);
}

Button1.Click()
{
准备好待发送的数据(&Data);
SetEvent(mutex.Handle);//这时候waitfor能马上返回,数据发出去,客户端的get马上返回
}
 
可能不行吧,等太久,客户端应该会自己断开,然后说打不开网页。
你自己测过没有?要没什么问题,这也是个方法。
 
嗯,代码中
while true
{
idhttp.get('http://ip/?packetType=心跳包&cmd=我要做啥',60秒);
}
的意思是如果超时(60秒)就进入下一个心跳循环。当然如果有异常之类的话要处理一下。
 
无忧站网络——专业提供虚拟主机、域名注册、网页制作、LOGO制作、网站推广等服务。
更多空间详情请登陆 http://www.51zhan.com
 
这种用TCP的长连接不可取,客户端多的话服务器的会顶不住的。
 
如果是client连接server后,由server来推业务数据的话,这种方式确实不太可行。
一来http频繁连接,造成服务器负担比较大(但是客户端少于100的话,优化server后应该问题不大)
二来要不停地查询才能保证业务数据的实时性。
我的意见供你参考:
1.使用udp通讯,客户端发起udp连接服务端(在应用层的虚连接),然后定时握手。但要研究NAT网关从外网到内网的通讯,但这个问题应该不大,因为服务器在公网上。只是NAT网关要维护这个udp打的洞,有点负担吧--不过QQ软件起码会开5个洞
服务器有数据要推送,用udp通知client,然后按你原来的soap来取数据。

2.使用tcp通讯,服务端用完成端口-据说可以极大提高服务器连接数,但我未试过,机制与udp一样,只是tcp实现虚连接,所以应用层编码比较方便了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部