Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make servicestack use an unbuffered response stream?

I want to send messages back to a client via a stream. I want the client to start processing these messages as soon as possible (before the server has completed the streaming on the server side).

I have implemented IStreamWriter and I have a service which returns the IStreamWriter implementation.

public class StreamingService : Service
{
    public object Any(MyStreamRequest request)
    {
        return new MyStreamWriter(request);
    }
}

Where MyStreamRequest is defined like this:

[DataContract]
public class StreamRequest : IReturn<Stream>
{
    [DataMember]
    public int HowManySecondsToProduceData { get; set; }
}

When I test my implementation in a self-hosted environment it works perfectly. However, when I host this in IIS, the get call from the client

var client = new ProtoBufServiceClient("");
Stream stream = client.Get(new StreamRequest { HowManySecondsToProduceData = 20};

does not return until the IStreamWriter.WriteTo call returns (20 seconds in the sample above). This prevents my client from processing the stream right away and will also cause failure in high volume cases. I do call responseStream.Flush() inside my IStreamWriter.WriteTo implementation.

Does anybody have any insight on why this does not work in the IIS scenario, but only for the self hosted case? What do I need to do differently?

It seems like a likely cause of this problem is that the servicestack response stream is set to use buffering. I cannot find a way to change this though. Is it possible?

like image 845
Trond Avatar asked Feb 01 '26 21:02

Trond


2 Answers

You just need to disable ASP.Nets response buffering:

public class NoBufferAttribute : RequestFilterAttribute
{
    public override void Execute( IHttpRequest req, IHttpResponse res, object requestDto )
    {
        var originalResponse = (System.Web.HttpResponse)res.OriginalResponse;
        originalResponse.BufferOutput = false;
    }
}

John

like image 136
JJJ Avatar answered Feb 04 '26 15:02

JJJ


I found a solution myself: The solution to this problem is quite simple: Call IHttpResponse Flush() inside the IStreamWriter.WriteTo implementation when you want to send data to the client. You get the IHttpResponse by calling base.Response inside the Service implementation.

like image 24
Trond Avatar answered Feb 04 '26 15:02

Trond



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!