2013-05-09 25 views
7

Tôi có một thiết bị sử dụng các dịch vụ Web an toàn và tôi đã sử dụng chức năng yêu cầu/phản hồi của nó, nhờ đó tôi gửi lệnh qua HTTP GET và nó phản hồi bằng XML thích hợp.Làm cách nào để nhận được thông báo đẩy với Indy?

Tôi hiện cần sử dụng thông báo mủ của thiết bị. Tôi đã thử cách tiếp cận tương tự như trên, theo đó tôi cung cấp quy trình TIdHTTP.Get với URL HTTP có liên quan và luồng để đưa ra phản hồi, nhưng điều này dường như không hoạt động. Cuộc gọi tới Get không quay lại. Điều này có ý nghĩa với tôi trong đó với các thông báo đẩy bạn đang mở một dòng truyền thông HTTP giữa thiết bị và chương trình và kết nối này sẽ vẫn mở để phát trực tuyến cho đến khi đóng.

Vấn đề của tôi là tôi không biết cách lấy XML từ luồng nếu phương thức Get không trả lại. Nó giống như chương trình đã treo. Tôi đã cố gắng đặt giao tiếp thông qua GET với thiết bị và đọc luồng vào một luồng để điều này có thể tiếp tục và sau đó ứng dụng chính của tôi có thể kiểm tra XML kết quả nhưng điều này cũng không hoạt động.

Tôi tự hỏi liệu tôi có quá phức tạp không và nếu có giải pháp đơn giản. Khi tôi chỉ cần gửi một yêu cầu và nhận được một phản hồi, nó hoạt động tốt; nó chỉ là sự thúc đẩy mà tôi không thể làm việc.

Nếu tôi sử dụng URL trong Internet Explorer, tôi có thể thấy XML được trả lại cũng như biểu trưng "bận" liên tục chạy cho biết luồng đang mở.

Tôi đã chạy lệnh thông qua trình duyệt của tôi Firefox Mozilla 20.0.1 và xem những gì wireshark chụp cho yêu cầu đẩy và phản hồi. Phần HTTP được hiển thị dưới đây:

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 

Yêu cầu Tôi cố gắng để làm trong Delphi được như sau:

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; 

Tôi cũng đã thử với 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; 

Bất kỳ trợ giúp trong việc vấn đề này sẽ được đánh giá cao.

SOLUTION


Trong trường hợp của tôi chỉ đơn giản là thêm từ khóa GET đến đầu của cuộc gọi làm việc. Tôi giả định các thành phần TCP kết nối đòi hỏi kiến ​​thức về những gì hành động (tức là GET PUT vv) nó là bạn muốn làm, nó không thể đọc được suy nghĩ của tôi, làm cho tinh thần

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

Gợi ý: trên Stackoverflow, bạn có thể thêm giải pháp của mình làm câu trả lời (và chấp nhận) – mjn

Trả lời

3

TIdHTTP không hỗ trợ server-side đẩy vào thời điểm này (và thậm chí sau đó, có nhiều cách mà phía máy chủ đẩy có thể được thực hiện - cái nào là dịch vụ REST của bạn bằng cách sử dụng?). Bạn sẽ phải chuyển sang TIdTCPClient, định dạng và gửi yêu cầu HTTP theo cách thủ công, sau đó sử dụng bộ hẹn giờ hoặc chuỗi để đọc và phân tích cú pháp phản hồi được đẩy khi cần.

+0

Tôi không cho rằng bạn có thể cung cấp cho tôi một ví dụ đơn giản về cách thực hiện việc này? Tôi đã cập nhật mã của tôi để sử dụng TidTCPClient thay vì bây giờ và sau khi một số fiddling có một số hình thức phản ứng lại nhưng nó là HTML. Hình như thông tin tiêu đề tài liệu. Không có XML được trả về. Không thể tìm thấy ví dụ tốt về cách thực hiện việc này. thnx – MarkZA

+1

Tôi đề nghị bạn sử dụng gói sniffer, chẳng hạn như Wireshark hoặc Fiddler, để xem IE đang yêu cầu URL như thế nào, sau đó sao chép các giá trị yêu cầu đó trong Indy. Đặc biệt là 'User-Agent' đặc biệt, vì một số máy chủ gửi nội dung khác nhau cho các kiểu máy khách khác nhau, và khi nói đến việc đẩy máy chủ, máy chủ web có khả năng sử dụng các kiểu push khác nhau cho các kiểu trình duyệt web khác nhau vì không có tiêu chuẩn hóa định dạng cho đẩy mà mọi người đều đồng ý. Nếu bạn cập nhật câu hỏi của mình bằng ví dụ về một lần nhấn được chụp bởi trình thám thính, tôi có thể chỉ cho bạn cách sao chép nó bằng 'TIdTCPClient'. –

+0

Xin chào. Không hoàn toàn chắc chắn những gì bạn đang tìm kiếm. Tôi đã chạy lệnh thông qua trình duyệt của tôi và nhìn thấy những gì wireshark chụp cho các yêu cầu đẩy. Phần HTTP được hiển thị bên dưới: GET/elite/notifications/stream? Resume = 2013-05-06T00: 00: 00Z HTTP/1.1 Máy chủ: 192.168.10.10 Tác nhân người dùng: Mozilla/5.0 (Windows NT 6.1; WOW64; rv: 20.0) Gecko/20100101 Firefox/20.0 Chấp nhận: text/html, application/xhtml + xml, application/xml; q = 0.9, */*; q = 0.8 Accept-Language: en-US, vi; q = 0.5 Accept-Encoding: gzip, deflate Kết nối: keep-alive – MarkZA

0

Ứng dụng khách HTTP (TIdHTTP) trong thân của Indy 10.6 bây giờ cũng hỗ trợ "Server Push", nếu máy chủ gửi một phản ứng multipart/...:

New TIdHTTP hoNoReadMultipartMIME flag

Một lá cờ hoNoReadMultipartMIME mới đã được thêm vào tài sản TIdHTTP.HTTPOptions. Mục đích của lá cờ này là chỉ định liệu TIdHTTP có nên đọc nội dung của "multipart/..." câu trả lời hay không, chẳng hạn như "multipart/x-mixed-replace" hoặc "multipart/byteranges", vào TStream mục tiêu hoặc để thoát ngay lập tức và để người gọi đọc nội dung theo cách thủ công thay thế.

Vì có nhiều cách khác nhau để triển khai Server Push, câu trả lời này có thể hữu ích hơn hoặc ít hơn cho một máy chủ nhất định.

Các vấn đề liên quan