102 lines
3.3 KiB
C#
102 lines
3.3 KiB
C#
using Microsoft.Owin;
|
|
using Owin;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using System.Web.Http;
|
|
|
|
namespace OwinProject.OWIN
|
|
{
|
|
public class StartupSSE
|
|
{
|
|
|
|
|
|
public void Configuration(IAppBuilder app)
|
|
{
|
|
var api = new Api();
|
|
app.Run(context => api.Invoke(context));
|
|
}
|
|
|
|
public class Subscriber
|
|
{
|
|
private StreamWriter _writer;
|
|
private TaskCompletionSource<bool> _tcs;
|
|
public Subscriber(Stream body, TaskCompletionSource<bool> tcs)
|
|
{
|
|
this._writer = new StreamWriter(body);
|
|
this._tcs = tcs;
|
|
}
|
|
|
|
public async void WriteAsync(string message)
|
|
{
|
|
try
|
|
{
|
|
_writer.Write(message);
|
|
_writer.Flush();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (e.HResult == -2146232800) // non-existent connection
|
|
_tcs.SetResult(true);
|
|
else
|
|
_tcs.SetException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
public class Api
|
|
{
|
|
System.Timers.Timer _timer = new System.Timers.Timer(500);
|
|
List<Subscriber> _subscribers = new List<Subscriber>();
|
|
public Api()
|
|
{
|
|
_timer.Elapsed += _timer_Elapsed;
|
|
}
|
|
|
|
void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
|
{
|
|
UpdateSubscribers();
|
|
}
|
|
|
|
public void UpdateSubscribers()
|
|
{
|
|
Console.WriteLine("updating {0} subscribers", _subscribers.Count);
|
|
var subscribersCopy = _subscribers.ToList<Subscriber>();
|
|
var msg = String.Format("Hello async at {0}\n", DateTime.Now);
|
|
subscribersCopy.ForEach(w => w.WriteAsync(msg));
|
|
_timer.Start();
|
|
}
|
|
|
|
|
|
public Task Invoke(IOwinContext context)
|
|
{
|
|
SetEventHeaders(context);
|
|
System.IO.Stream responseStream = context.Environment["owin.ResponseBody"] as Stream;
|
|
var tcs = new TaskCompletionSource<bool>();
|
|
var s = CreateSubscriber(responseStream, tcs);
|
|
tcs.Task.ContinueWith(_ => _subscribers.Remove(s));
|
|
Console.WriteLine("Add subscriber. Now have {0}", _subscribers.Count);
|
|
s.WriteAsync("Registered\n");
|
|
_timer.Start();
|
|
return tcs.Task;
|
|
}
|
|
|
|
private Subscriber CreateSubscriber(System.IO.Stream responseStream, TaskCompletionSource<bool> tcs)
|
|
{
|
|
var s = new Subscriber(responseStream, tcs);
|
|
_subscribers.Add(s);
|
|
return s;
|
|
}
|
|
|
|
private static void SetEventHeaders(IOwinContext context)
|
|
{
|
|
context.Response.ContentType = "text/eventstream";
|
|
context.Response.Headers["Transfer-Encoding"] = "chunked";
|
|
context.Response.Headers["cache-control"] = "no-cache";
|
|
}
|
|
}
|
|
}
|
|
}
|