How can I pass a response from WCF without buffering?

I have a quiet (webHttpBinding) self-service WCF service. Most methods return an xml or json version of objects to the client.

I have several GET methods that run long methods, and I would like to pass the log response to the browser (or application) so that the user knows what is happening. This would be easy to accomplish using HttpContext.Current.Response.OutputStream.Write . Unfortunately, HttpContext.Current always null in the WCF self-service, even if I aspNetCompatibilityEnabled configuration (unfortunately, IIS is not an option).

I tried AnonymousPipeServerStream : WCF and streaming requests and responses

along with the first setup:

 OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse; context.ContentType = "text/plain"; 

so that the answer gets into the browser, it does not load the stream into a file for saving.

In Chrome, it doesn't work at all - it buffers to the end. In IE or wget, it seems that the buffer is about 4k (or something else) at a time. This is not suitable for logging, because if I did not spit out unnecessary log messages to force output, the user really does not know what is happening. I can only assume that this is because the answer is actually a block answer, and 4k chunks (and not just a write to the output stream).

The fix in order to get chrome for output, apparently, should write some garbage to the content before sending the delayed response: Chunked transfer encoding is the behavior of the browser , however I donโ€™t think it is possible with WCF.

So, the possible solutions I'm looking for are:

  • A way to write to the output stream in WCF in a standalone service (without IIS). or
  • A way to control the block sizes in a streaming response (& a way to write some content first so that Chrome displays the pieces).

Another option, I suppose, is to abandon WCF in favor of something more REST-friendly (I'm starting to think that WCF was not the right choice). However, having written so much in WCF, this seems like a tedious task. If I cannot switch to this, it will be a simple migration (for example, if I can reuse the same classes of service, perhaps with only different attributes). Nancy maybe?

+7
c # rest stream wcf
source share
3 answers

I did something like what you are asking about here too. I wrote a WCF service (BasicHttpBinding), which performed both streaming and buffering of data to client devices that use my service to synchronize data. Streaming is tough, as you probably figured out, and I donโ€™t think there is a way to "write to the stream."

In a basic sense, Streaming on a WCF service works the same way as File.IO works, as shown in the code below

  FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); 

If the specified file is 1 GB, your stream will start returning bytes before reading it to the end of the file. WCF streaming works the same way (in fact, it implements FileStream, in my experience), so it is good for huge chunks of data. He reads ... he sends; he reads ... he sends. Therefore, I am not sure how you enter some information into this stream for display.

Having said that, our Synchronous User Interface displays the number of bytes being pulled down, plus percentage completion, so that users do not turn off the machine or cancel it. We do this using a separate stream that reads the size of the downloaded file every 10 seconds and calculates the percentage value of the integer (the full size is sent back as a parameter in the response), and then writes the results to the user interface results window, Thus, the solution is actually quite just in our case.

+2
source share

I am doing video streaming as follows:

Group the methods that return the data to be transferred to the endpoint, and then add the stream transferMode to this endpoint.

Here is the configuration I'm using (for basicHttpBinding).

 <services> <service name="CustomersService"> <endpoint address="FilesService.svc" binding="basicHttpBinding" bindingConfiguration="StreamedBinding" contract="Soap.Interfaces.IFilesService" /> </service> </services> 

and define the binding configuration:

 <bindings> <basicHttpBinding> <binding name="IntersolveWebServicesStreamedBinding" allowCookies="true" transferMode="Streamed" maxReceivedMessageSize="67108864" /> </basicHttpBinding> </bindings> 

Basically, you should set transferMode in the binding configuration.

I have not tried this with webHttpBinding, so please let me know if this works for you.

0
source share

Just trick the browser into thinking there is an HTML response with Multipart Content-Type

http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html

I used this for quite a few things, including MJPEG, but you can also use it for COMET / WebSocket as answers.

0
source share

All Articles