基本需求:
Client在内网,Server在公网。当Client连上Server后,Server由用户操作,可随时向Client发命令。Client实时执行完后返回结果给Server,Server处理并显示执行结果。以上过程希望通过SOAP实现,不知Delphi中可否实现异步SOAP或回调?还有一个半成品的思路:Client在一个心跳周期中问Server:我需要做什么?然后阻塞
Server不马上回答,直到用户指定了某操作了以后,才回答:你要做XXX。(这一步是否可以用线程中加WaitForSingleObject?)
Client收到这个回复,执行XXX操作,把结果送回服务器,并要求下一轮:“我需要做什么?”
若Server的回复超过了1个心跳周期,Client重复上述过程。Server也使用定时器清除过期的请求。当然如果SOAP可以做到Server随时调Client中的函数,上面的所有机制都不用了。不知道Delphi中的SOAP能否满足上述需求?
Client在内网,Server在公网。当Client连上Server后,Server由用户操作,可随时向Client发命令。Client实时执行完后返回结果给Server,Server处理并显示执行结果。以上过程希望通过SOAP实现,不知Delphi中可否实现异步SOAP或回调?还有一个半成品的思路:Client在一个心跳周期中问Server:我需要做什么?然后阻塞
Server不马上回答,直到用户指定了某操作了以后,才回答:你要做XXX。(这一步是否可以用线程中加WaitForSingleObject?)
Client收到这个回复,执行XXX操作,把结果送回服务器,并要求下一轮:“我需要做什么?”
若Server的回复超过了1个心跳周期,Client重复上述过程。Server也使用定时器清除过期的请求。当然如果SOAP可以做到Server随时调Client中的函数,上面的所有机制都不用了。不知道Delphi中的SOAP能否满足上述需求?
你在soap service建立一个需要返回值的函数,当client调用的时候,它会等待这个值,想当于阻塞,但是时间你需要把握一下.
/****当然如果SOAP可以做到Server随时调Client中的函数*****/
你把server和client角色对调一下即可.其他不知道.
除非你把客户端写成一个windows服务程序,一启动系统就向服务器发一个请求操作的信息
不过担心这个会不太稳定。
把server和client角色对调的话,代码怎么写?因为Client永远在内网,Server是无法调用Client提供的Web Service的。。to dabaicai:
我原文中有写“若Server的回复超过了1个心跳周期,Client重复上述过程。”
不过想想这个好像也不好实现。不知怎么打断阻塞的函数。
用 TThread.Terminate 的话是假的打断,到时候会积累很多空线程
用 TThread.Abort 的话又太狂暴了,会资源泄漏思路又阻塞了,请高手指点。
client 询问我做什么?
server 将询问储存在缓冲里,返回默认值:等待。
用户指定操作,server将缓冲里这个client的行为由等待替换为相应的值:你做这个好了;
client 等待一段时间后询问:我做什么。
server 查询缓冲,回答:哦,你做这个好了。
client 等待一段时间后询问:我做什么。 <== 这里有写问题
这样就不实时了..
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马上返回
}
我可以负责的告诉你,这种想法很失败。tcp的实时是阻塞来的,是建立在tcp的协议上的。
你居然使用soap来做实时?
做好一个及时的就不错了。要不你还是用select 或者iocp算了。
用idTCP已经做出来实时S->C / C->S了。
select和iocp都是比较底层的模型。
我认为http和soap都是应用层的协议,应该可以服务于select或iocp之上。
但是http和soap的封装可能丧失了TCP的某些特性,比如说S->C主动发送。
您看看楼上的楼上这样写有没有漏洞?
除非客户端建立一个通信服务,服务器像要发送命令则连接这个服务端口
,客户'听'到了这个命令立刻去做xxx。
要不你去参考ajax?代码我看不懂,
你的思路颠覆了我对ws的认识,
我需要回去清醒一下。
谢谢回复,你提到的几个我也有些迷茫,只能黑盒地看这个问题:
httpClient中调get方法,在超时之前,是一直阻塞在那里的,做过实验。我觉得“http根本没有连接,你怎么阻塞”这个问题应该这样回答:Http没有连接,但TCP有连接。httpClient.Get阻塞是可能的。“除非客户端建立一个通信服务,服务器像要发送命令则连接这个服务端口”
这句的解释可以用FTP的PORT模式来解释(相反的是PASV模式)。PORT模式之所以几乎被淘汰是因为服务器几乎无法发起连接到客户端。Ajax用XmlHttpRequest对象,搞不懂它是怎么通讯的,居然可以做到客户端被动接收Xml。期待高人指点。
我的理解也是这样的,但是实际上Ajax就能做到异步回调,我也很迷惑。
下面贴一段ajax的典型代码,一起学习。
=============================================/** XHConn - Simple XMLHTTP Interface - [email protected] - 2005-04-08 **
** Code licensed under Creative Commons Attribution-ShareAlike License **
** http://creativecommons.org/licenses/by-sa/2.0/ **/
function XHConn()
{
var xmlhttp, bComplete = false;
try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
catch (e) { try { xmlhttp = new XMLHttpRequest(); }
catch (e) { xmlhttp = false; }}}
if (!xmlhttp) return null;
this.connect = function(sURL, sMethod, sVars, fnDone)
{
if (!xmlhttp) return false;
bComplete = false;
sMethod = sMethod.toUpperCase(); try {
if (sMethod == "GET")
{
xmlhttp.open(sMethod, sURL+"?"+sVars, true);
sVars = "";
}
else
{
xmlhttp.open(sMethod, sURL, true);
xmlhttp.setRequestHeader("Method", "POST "+sURL+" HTTP/1.1");
xmlhttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
}
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && !bComplete)
{
bComplete = true;
fnDone(xmlhttp);
}};
xmlhttp.send(sVars);
}
catch(z) { return false; }
return true;
};
return this;
}
============================注意 xmlhttp.onreadystatechange = function(){ ...
这句话也可以将onreadystatechange指向另一个写好的函数。这样当onreadystatechange触发的时候,就跳到该函数,实现异步回调。不知道"Msxml2.XMLHTTP"是怎么实现它的。
是可以实现的。
IE从 XXX.0 开始(忘记版本了 )就在内嵌了一个 XXX 器(忘记名字),有了这个小东西,Ajax 才能发挥自如, 如果用户更换浏览器为 XXX.0 - 1 版本,肯定 Ajax 是发挥不了作用的。