2013-05-09 11 views
7

Possiedo un dispositivo che utilizza servizi Web riposanti e che ho utilizzato la sua funzionalità di richiesta/risposta con cui invio un comando tramite HTTP GET e risponde con l'XML appropriato.Come si ricevono le notifiche push con Indy?

Ora devo utilizzare le notifiche pus del dispositivo. Ho provato lo stesso approccio di cui sopra in cui fornisco la procedura TIdHTTP.Get con l'URL HTTP pertinente e lo stream in cui inserire la risposta, ma questo non sembra funzionare. La chiamata a Get non torna indietro. Questo ha senso per me in quanto con le notifiche push si sta aprendo un flusso HTTP di comunicazione tra il dispositivo e il programma e questa connessione rimarrà aperta per lo streaming fino alla chiusura.

Il mio problema è che non so come ottenere l'XML dallo stream se il metodo Get non restituisce. È come se il programma fosse bloccato. Ho provato a mettere la comunicazione tramite GET con il dispositivo e la lettura dello stream in un thread in modo che questo possa continuare da solo e quindi la mia applicazione principale può semplicemente controllare l'XML risultante, ma anche questo non funziona.

Mi chiedo se sono troppo complicato e se c'è una soluzione semplice. Quando invio semplicemente una richiesta e ottengo una risposta, funziona correttamente; è solo lo streaming push che non riesco a far funzionare.

Se utilizzo l'URL in Internet Explorer, è possibile vedere l'XML restituito e il logo "occupato" costantemente in esecuzione che indica che lo streaming è aperto.

Ho eseguito il comando tramite il mio browser Firefox Mozilla 20.0.1 e ho visto ciò che wireshark acquisisce per la richiesta push e la risposta. La parte HTTP è la seguente:

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 

La richiesta che sto cercando di fare in Delphi è la seguente:

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; 

ho anche provato con 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; 

Tutta l'assistenza in questa questione sarebbe apprezzata.

SOLUZIONE


Nel mio caso la semplice aggiunta la parola chiave GET per l'inizio della chiamata ha funzionato. Ho assunto la componente connessione TCP richiede la conoscenza di quale azione (cioè avere messo ecc) è che si desidera fare, cant leggere la mia mente, ha senso

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

Suggerimento: su Stackoverflow, è possibile aggiungere la soluzione come risposta (e accettarla) – mjn

risposta

3

TIdHTTP non supporta lato server spinge in questo momento (e anche in questo caso, ci sono molti modi in cui è possibile implementare i push sul lato server - quale dei due è il servizio REST che utilizza?). Dovrai passare a TIdTCPClient, formattare e inviare manualmente la richiesta HTTP, quindi utilizzare un timer o un thread per leggere e analizzare le risposte inviate quando necessario.

+0

Non credo che tu possa fornirmi un semplice esempio di come farlo? Ho aggiornato il mio codice per utilizzare il TidTCPClient e ora, dopo alcuni giochetti, ho ricevuto qualche forma di risposta, ma è HTML. Sembra informazioni sull'intestazione del documento. Non viene restituito alcun XML. Non riesco a trovare buoni esempi su come farlo. thnx – MarkZA

+1

Ti suggerisco di usare uno sniffer di pacchetti, come Wireshark o Fiddler, per vedere come IE richiede l'URL, quindi duplicare quei valori di richiesta in Indy. Soprattutto l''User-Agent' in particolare, poiché alcuni server inviano contenuti diversi per diversi tipi di client e quando si tratta di server push, è probabile che un server web utilizzi diversi tipi di push per diversi tipi di browser poiché non c'è standardizzazione formato per spinte su cui tutti sono d'accordo. Se aggiorni la tua domanda con un esempio di push acquisito da uno sniffer, posso mostrarti come replicarlo con 'TIdTCPClient'. –

+0

Ciao. Non del tutto sicuro di cosa stai cercando. Ho eseguito il comando tramite il mio browser e ho visto cosa cattura wireshark per la richiesta push. La parte HTTP è la seguente: 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 Accetta: 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 Connessione: keep-alive – MarkZA

0

Il client HTTP (TIdHTTP) nel trunk di Indy 10.6 ora supporta anche "server push", se il server invia una risposta multipart/...:

New TIdHTTP hoNoReadMultipartMIME flag

Una nuova bandiera hoNoReadMultipartMIME è stato aggiunto alla proprietà TIdHTTP.HTTPOptions. Lo scopo di questo flag è specificare se TIdHTTP deve leggere il contenuto del corpo di "multipart/..." risposte, come "multipart/x-mixed-replace" o "multipart/byteranges", nel TStream di destinazione o per uscire immediatamente da e consentire al chiamante di leggere il contenuto manualmente.

Poiché ci sono molti modi diversi per implementare Server Push, questa risposta può essere più o meno utile per un determinato server.