2013-05-09 46 views
7

我有一个使用平静的Web服务的设备,我使用了它的请求/响应功能,我通过HTTP GET向它发送一个命令,并使用适当的XML进行响应。如何通过Indy接收推送通知?

我现在需要使用设备的脓液通知。我已经尝试了与上述相同的方法,因此我为TIdHTTP.Get过程提供了相应的HTTP URL和流以放置响应,但这似乎不起作用。拨打Get不会回来。这对我来说很有意义,因为通过推送通知,您将在设备和程序之间打开HTTP通信流,并且此连接将保持开放状态,直到关闭为止。

我的问题是,虽然我不知道如何从流获取XML如果Get方法不返回。这就好像程序已经挂起。我试图通过GET与设备进行通信,并将流读入线程,以便它可以自行继续,然后我的主应用程序可以检查结果XML,但这也不起作用。

我想知道如果我在这个复杂,如果有一个简单的解决方案。当我简单地发送请求并获得响应时,它工作正常;这只是推送流,我无法工作。

如果我使用Internet Explorer中的URL,我可以看到返回的XML以及“忙”标志的持续运行,表明该流是开放的。

我已经通过我的浏览器Firefox的Mozilla的20.0.1运行命令,并看到了推送请求和响应捕捉什么Wireshark的。该HTTP部分如下图所示:

GET /elite/notifications/stream?resume=2013-05-06T00:00:00Z HTTP/1.1 
Host: 192.168.10.10 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 

我想在Delphi做的是如下请求:

if fEventStream = nil then 
    fEventStream := TStringStream.Create(''); 
try 
    TapItem.fHTTP.Get(TapItem.I2IReaderIP+'/elite/notifications/stream?resume=2013-05-01T00:00:00Z',fEventStream); 
    TapItem.fEventXML := fEventStream.ReadString(fEventStream.Size); 
except 
    on e:exception do begin 
    ShowMessage(e.message) 
    end; 
end; 

我也试图与TidTCPConnection

fTCPConn.IOHandler.Writeln(TapItem.I2IReaderIP+I2I_PUSH_EVENT+'2013-05-01T00:00:00Z'); 
    While not Terminated do begin 
    XMLString := XMLString + fTCPConn.IOHandler.Readln; 
    end; 

中的任何援助这个问题将不胜感激。

SOLUTION


在我的情况简单地把GET关键字通话的开始工作。我以为TCP连接组件需要什么样的行动方面的知识(即GET PUT等),它是你想这样做,它不能读懂我的心思,是有道理的

fTCPConn.IOHandler.Writeln('GET ' + TapItem.I2IReaderIP+I2I_PUSH_EVENT+'2013-05-01T00:00:00Z'); 
While not Terminated do begin 
    XMLString := XMLString + fTCPConn.IOHandler.Readln; 
end; 
+0

提示:在Stackoverflow上,您可以添加您的解决方案作为答案(并接受它) – mjn 2014-03-06 13:11:41

回答

3

TIdHTTP不支持服务器端推送此时(即使这样,服务器端推送可以有多种方式实现 - 哪一种是您的REST服务使用的?)。您将不得不切换到TIdTCPClient,手动格式化并发送HTTP请求,然后使用定时器或线程在到达时根据需要读取和解析推送的响应。

+0

我不认为你可以提供一个简单的例子来说明如何做到这一点?我已经更新了我的代码,现在改用了TidTCPClient,并且在一些调整之后得到了某种形式的响应,但它是HTML。看起来像文件头信息。没有XML被返回。不能找到如何做到这一点的好例子。 thnx – MarkZA 2013-05-10 07:10:28

+1

我建议你使用Wireshark或Fiddler等数据包嗅探器来查看IE如何请求URL,然后在Indy中复制这些请求值。特别是'User-Agent',因为有些服务器针对不同类型的客户端发送不同的内容,并且当涉及到服务器推送时,web服务器可能针对不同类型的web浏览器使用不同类型的推送,因为没有标准化格式推动每个人都同意。如果您通过嗅探器捕获的推送示例更新您的问题,我可以向您展示如何使用“TIdTCPClient”进行复制。 – 2013-05-10 07:32:08

+0

嗨。不完全确定你在找什么。我已经通过浏览器运行该命令,并查看了wireshark捕获的推送请求。 HTTP部分如下所示:GET/elite/notifications/stream?resume = 2013-05-06T00:00:00Z HTTP/1.1 Host:192.168.10.10 User-Agent:Mozilla/5.0(Windows NT 6.1; WOW64; rv:20.0)Gecko/20100101 Firefox/20.0 Accept:Language/html,application/xhtml + xml,application/xml; q = 0.9,*/*; q = 0.8 012- = 0.5 Accept-Encoding:gzip,deflate Connection:keep-alive – MarkZA 2013-05-10 08:58:37

0

在印10的躯干的HTTP客户端(TIdHTTP)。6现在还支持“服务器推送”,如果服务器发送一个响应multipart/...

New TIdHTTP hoNoReadMultipartMIME flag

新hoNoReadMultipartMIME标志已经被添加到 TIdHTTP.HTTPOptions财产。此标志的用途是指定 TIdHTTP是否应将“multipart/...” 响应(例如“multipart/x-mixed-replace”或 “multipart/byteranges”)的正文内容读入目标TStream或立即退出 并让调用者手动读取内容。

由于有很多不同的方法来实现服务器推送,这个答案可能对给定的服务器或多或少有帮助。