I just started messing with my own implementation of ServiceStack server events.
After reading the wiki section and reading the code of the chat application, I started creating my own new mvc4
project and installing all the ServiceStack libraries via nuGet.
After configuring and creating the AppHost
, I created a new "helloworld" service and started the site, just to make sure it worked (it worked indeed).
Now the main issues. Based on the existing example code (the chat application), I created the new HTML page and the service which calls ServerEvents.NotifyChannel
and then I started the new site.
When calling the service via ajax (post) the debugger hits the break point, but the client events aren't fired when the service returns. Even more, it seems that the notify is sort of "cached/delayed" and when calling the service the second time, the client receives the data from the first call.
Should I use servicestack.razor
views? Should I create another MVC application and again, build everything from scratch to test it?
editing this post to add code (as pointed out): https://github.com/xspadax/SS_SSE_Test
This issue is due to Flush()
not working properly in ASP.NET MVC projects which seems to automatically buffer when compression is enabled, it can be disabled for dynamic pages with:
<system.webServer>
<urlCompression doStaticCompression="true" doDynamicCompression="false" />
</system.webServer>
Incidentally not even the explicit API for Buffering output seems to have any effect when compression is enabled:
Response.BufferOutput = false;
Normal ASP.NET projects that don't use ASP.NET MVC like ServiceStack + Razor doesn't have this issue.
Alternative code-only solution
New API's were added in v4.0.32+ that's now available on MyGet to provide more custom hooks into ServiceStack's Server Events Feature, OnInit
can be used to modify the HTTP Headers of the Server Events Stream, whilst the OnPublish()
callback is fired after every message is published:
Plugins.Add(new ServerEventsFeature {
/*
OnInit = req => { //fired when sending headers in server event stream
var res = (HttpResponseBase)req.Response.OriginalResponse; //Get MVC Response
res.BufferOutput = false; // Should make Flush() work, but doesn't
},
*/
OnPublish = (res, msg) => { //fired after ever message is published
res.Write("\n\n\n\n\n\n\n\n\n\n");
res.Flush();
}
});
The solution above involves writing a number of trailing \n
lines to force a flush in MVC. It's a valid alternative solution as trailing new lines are ignored in Server Sent Events.