Ho un servizio WCF (webHttpBinding) di tipo host autonomo. La maggior parte dei metodi restituisce la versione xml o json degli oggetti al client.Come posso eseguire lo streaming di una risposta da WCF senza buffering?
Ho un paio di metodi GET che attivano metodi a esecuzione prolungata e mi piacerebbe trasmettere la risposta del registro al browser (o all'applicazione) in modo che l'utente sappia cosa sta succedendo. Questo sarebbe semplice da realizzare con HttpContext.Current.Response.OutputStream.Write
. Sfortunatamente, HttpContext.Current
è sempre nullo in un servizio WCF auto-ospitato, anche se includo la configurazione aspNetCompatibilityEnabled
(IIS non è un'opzione purtroppo).
ho provato AnonymousPipeServerStream
: WCF and streaming requests and responses
insieme prima impostazione:
OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
context.ContentType = "text/plain";
in modo che la risposta arriva nel browser che non scarica il flusso in un file da salvare.
In Chrome non funziona affatto, si blocca fino alla fine. In IE o wget sembra buffer per circa 4k (o qualcosa) alla volta. Questo non va bene per la registrazione, a meno che non sputi un sacco di messaggi di log non necessari per forzare l'output, l'utente non sa veramente cosa sta succedendo. Posso solo supporre che ciò sia dovuto al fatto che la risposta è in realtà una risposta frammentata e che i blocchi sono 4k (anziché solo scrivere sull'output).
La correzione per ottenere il chrome all'output è apparentemente di scrivere dei rifiuti nel contenuto prima di inviare la risposta chunked: Chunked transfer encoding - browser behavior, tuttavia, non penso sia possibile con WCF.
Così, le possibili soluzioni sto cercando:
- Un modo di scrivere al OutputStream in WCF in un servizio in hosting di sé (senza IIS). o
- Un modo per controllare le dimensioni del blocco in una risposta di flusso (& un modo per scrivere prima alcuni contenuti in modo che Chrome esegua il rendering dei blocchi).
Un'altra opzione, suppongo, è di abbandonare WCF in favore di qualcosa di più REST-friendly (sto iniziando a pensare che il WCF non fosse la scelta giusta). Tuttavia, avendo scritto così tanto in WCF ora, questo sembra un compito noioso. A meno che non ci sia qualcosa su cui posso passare, sarebbe una migrazione facile (ad esempio se potessi riutilizzare le stesse classi di servizio, magari con solo attributi diversi). Nancy forse?
Quindi, secondo te, quello che sto cercando di fare proprio non è possibile? – David
Suppongo che dipenda da cosa stai provando a trasmettere. Sono dati grezzi che stai spostando da un posto all'altro? Lo streaming viene solitamente utilizzato per enormi set di dati (ad esempio, trasmettiamo musica e film da Amazon) e una volta avviato lo streaming, il client e l'host si trovano a un passo, l'invio e la ricezione fino al termine del processo. Non sono sicuro di come o perché vorresti iniettare qualcosa in quel tipo di flusso. Se sei preoccupato per il tuo utente che fa qualcosa di strano perché non vede progressi, ci sono modi (come descrivo) attorno a quel problema. – Brian
Sto provando a trasmettere le informazioni di registrazione (vedere OP). Quindi la quantità di dati potrebbe variare da poche righe (se le cose vanno bene) a 1000s di linee se le cose vanno male. Questo è qualcosa che ho fatto in passato senza problemi scrivendo sul flusso di output (in .NET e in altri linguaggi), ma il problema sembra essere che WCF non mi dà la flessibilità che sto cercando. – David