7

我有一个使用 RESTful Web 服务的设备,我使用了它的请求/响应功能,通过 HTTP GET 向它发送一个命令,它用适当的 XML 响应。

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

Get我的问题是,如果方法不返回,我不知道如何从流中获取 XML 。就好像程序挂了一样。我试图通过 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;

在此问题上的任何帮助将不胜感激。

解决方案


在我的情况下,只需将 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;
4

2 回答 2

3

TIdHTTP目前不支持服务器端推送(即便如此,也有多种方式可以实现服务器端推送——您的 REST 服务使用哪一种?)。您必须TIdTCPClient手动切换到、格式化和发送 HTTP 请求,然后使用计时器或线程在推送响应到达时根据需要读取和解析它们。

于 2013-05-09T20:19:08.407 回答
0

Indy 10.6 主干中的 HTTP 客户端(TIdHTTP)现在也支持“服务器推送”,如果服务器发送multipart/...响应:

新的 TIdHTTP hoNoReadMultipartMIME 标志

TIdHTTP.HTTPOptions 属性中添加了一个新的 hoNoReadMultipartMIME 标志。此标志的目的是指定 TIdHTTP 是否应将“multipart/...”响应的主体内容(例如“multipart/x-mixed-replace”或“multipart/byteranges”)读入目标 TStream 或退出立即让调用者手动读取内容。

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

于 2014-03-06T13:02:37.273 回答