Quantcast
Channel: ASPNETWebStack Issue Tracker Rss Feed
Viewing all articles
Browse latest Browse all 7215

Commented Issue: PushStreamContent not working under Self hosting server [1169]

$
0
0
The code below it is supposed to write into the console the value of the current datetime every one second. It doesn't. But if the controller is hosted under IIS (instead of under SHS), it works fine.

Test code (console app):
```
using System;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Client {
using System.Web.Http;
using System.Web.Http.SelfHost;

class Program {
static readonly Uri _address = new Uri("http://localhost/ddsrpc/PushContent");

static void RunClient() {
HttpSelfHostServer httpServer = new HttpSelfHostServer(new HttpSelfHostConfiguration("http://localhost"));
httpServer.Configuration.Routes.MapHttpRoute("SseTransport", "ddsrpc/{controller}");
httpServer.OpenAsync().Wait();

HttpClient client = new HttpClient();

HttpRequestMessage request = new HttpRequestMessage {
Method = HttpMethod.Get,
RequestUri = _address,
};

client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ContinueWith(
getTask => {
if (getTask.IsCanceled) {
return;
}
if (getTask.IsFaulted) {
throw getTask.Exception;
}
HttpResponseMessage response = getTask.Result;

response.Content.ReadAsStreamAsync().ContinueWith(
(streamTask) => {
if (streamTask.IsCanceled) {
return;
}
if (streamTask.IsFaulted) {
throw streamTask.Exception;
}

byte[] readBuffer = new byte[512];
ReadResponseStream(streamTask.Result, readBuffer);
});
});
}

private static void ReadResponseStream(Stream rspStream, byte[] readBuffer) {
Task.Factory.FromAsync<byte[], int, int, int>(rspStream.BeginRead, rspStream.EndRead, readBuffer, 0, readBuffer.Length, state: null).ContinueWith(
(readTask) => {
if (readTask.IsCanceled) {
return;
}
if (readTask.IsFaulted) {
throw readTask.Exception;
}

int bytesRead = readTask.Result;
string content = Encoding.UTF8.GetString(readBuffer, 0, bytesRead);
Console.WriteLine("Received: {0}", content);

if (bytesRead != 0) {
ReadResponseStream(rspStream, readBuffer);
}
});
}

static void Main(string[] args) {
RunClient();

Console.WriteLine("Hit ENTER to exit...");
Console.ReadLine();
}
}

public class PushContentController : ApiController {
private static readonly Lazy<Timer> _timer = new Lazy<Timer>(() => new Timer(TimerCallback, null, 0, 1000));
private static readonly ConcurrentDictionary<StreamWriter, StreamWriter> _outputs = new ConcurrentDictionary<StreamWriter, StreamWriter>();

[HttpGet]
public HttpResponseMessage GetUpdates(HttpRequestMessage request) {
Timer t = _timer.Value;
request.Headers.AcceptEncoding.Clear();
HttpResponseMessage response = request.CreateResponse();
response.Content = new PushStreamContent(OnStreamAvailable, "text/plain");
return response;
}

private static void OnStreamAvailable(Stream stream, HttpContent headers, TransportContext context) {
StreamWriter sWriter = new StreamWriter(stream);
_outputs.TryAdd(sWriter, sWriter);
}

private static void TimerCallback(object state) {
foreach (var kvp in _outputs.ToArray()) {
try {
kvp.Value.Write(DateTime.Now);
kvp.Value.Flush();
} catch {
StreamWriter sWriter;
_outputs.TryRemove(kvp.Value, out sWriter);
}
}
}
}
}
```
Comments: The code above will not work for selfhost and needs to be modified. See below: using System; using System.IO; using System.Net; using System.Net.Http; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Collections.Concurrent; namespace Client { using System.Web.Http; using System.Web.Http.SelfHost; class Program { static readonly Uri _address = new Uri("http://localhost/ddsrpc/PushContent"); static void RunClient() { HttpClient client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage { Method = HttpMethod.Get, RequestUri = _address, }; client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ContinueWith( getTask => { if (getTask.IsCanceled) { return; } if (getTask.IsFaulted) { throw getTask.Exception; } HttpResponseMessage response = getTask.Result; response.Content.ReadAsStreamAsync().ContinueWith( (streamTask) => { if (streamTask.IsCanceled) { return; } if (streamTask.IsFaulted) { throw streamTask.Exception; } byte[] readBuffer = new byte[512]; ReadResponseStream(streamTask.Result, readBuffer); }); }); } private static void ReadResponseStream(Stream rspStream, byte[] readBuffer) { Task.Factory.FromAsync<byte[], int, int, int>(rspStream.BeginRead, rspStream.EndRead, readBuffer, 0, readBuffer.Length, state: null).ContinueWith( (readTask) => { if (readTask.IsCanceled) { return; } if (readTask.IsFaulted) { throw readTask.Exception; } int bytesRead = readTask.Result; string content = Encoding.UTF8.GetString(readBuffer, 0, bytesRead); Console.WriteLine("Received: {0}", content); if (bytesRead != 0) { ReadResponseStream(rspStream, readBuffer); } }); } static void Main(string[] args) { var config = new HttpSelfHostConfiguration("http://localhost"); config.Routes.MapHttpRoute("SseTransport", "ddsrpc/{controller}"); config.TransferMode = System.ServiceModel.TransferMode.Streamed; config.EnableSystemDiagnosticsTracing(); HttpSelfHostServer server = new HttpSelfHostServer(config); server.OpenAsync().Wait(); Console.WriteLine("Server started.."); RunClient(); Console.WriteLine("Hit ENTER to exit..."); Console.ReadLine(); } } public class PushContentController : ApiController { private static readonly Lazy<Timer> _timer = new Lazy<Timer>(() => new Timer(TimerCallback, null, 0, 1000)); private static readonly ConcurrentDictionary<StreamWriter, StreamWriter> _outputs = new ConcurrentDictionary<StreamWriter, StreamWriter>(); [HttpGet] public HttpResponseMessage GetUpdates(HttpRequestMessage request) { Timer t = _timer.Value; request.Headers.AcceptEncoding.Clear(); HttpResponseMessage response = request.CreateResponse(); response.Headers.Add("Access-Control-Allow-Origin", "*"); response.Headers.Add("Cache-Control", "no-cache, must-revalidate"); response.Content = new PushStreamContent(OnStreamAvailable, "text/event-stream"); return response; } private static void OnStreamAvailable(Stream stream, HttpContent headers, TransportContext context) { StreamWriter sWriter = new StreamWriter(stream); _outputs.TryAdd(sWriter, sWriter); } private static void TimerCallback(object state) { foreach (var kvp in _outputs.ToArray()) { try { kvp.Value.Write(DateTime.Now); kvp.Value.Flush(); } catch { StreamWriter sWriter; _outputs.TryRemove(kvp.Value, out sWriter); } } } } }

Viewing all articles
Browse latest Browse all 7215

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>