From 317fc97652c5a9e18152b7a15c686d35a4625c57 Mon Sep 17 00:00:00 2001 From: "Frank A. Krueger" Date: Mon, 12 Jun 2017 16:24:40 -0700 Subject: [PATCH] Add publishing to the server --- Ooui/Server.cs | 67 +++++++++++++++++++++++++++++++++++++++------- Samples/Program.cs | 2 ++ 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/Ooui/Server.cs b/Ooui/Server.cs index 0bf534d..510e1f1 100644 --- a/Ooui/Server.cs +++ b/Ooui/Server.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -9,6 +11,9 @@ namespace Ooui { public class Server { + readonly Dictionary> publishedPaths = + new Dictionary> (); + public Task RunAsync (string listenerPrefix) { return RunAsync (listenerPrefix, CancellationToken.None); @@ -22,22 +27,66 @@ namespace Ooui Console.WriteLine ($"Listening at {listenerPrefix}..."); while (!token.IsCancellationRequested) { - var listenerContext = await listener.GetContextAsync (); + var listenerContext = await listener.GetContextAsync ().ConfigureAwait (false); if (listenerContext.Request.IsWebSocketRequest) { ProcessWebSocketRequest (listenerContext, token); } else { - listenerContext.Response.StatusCode = 400; - listenerContext.Response.Close (); + ProcessRequest (listenerContext, token); } } } + public void Publish (string path, Func elementCtor) + { + System.Console.WriteLine($"PUBLISH {path}"); + publishedPaths[path] = elementCtor; + } + + public void Publish (string path, Element element) + { + Publish (path, () => element); + } + + void ProcessRequest (HttpListenerContext listenerContext, CancellationToken token) + { + var url = listenerContext.Request.Url; + var path = url.LocalPath; + + Console.WriteLine ($"{listenerContext.Request.HttpMethod} {url.LocalPath}"); + + Func ctor; + if (publishedPaths.TryGetValue (path, out ctor)) { + var element = ctor (); + RegisterElement (element); + WriteElementHtml (element, listenerContext.Response); + } + else { + listenerContext.Response.StatusCode = 404; + listenerContext.Response.Close (); + } + } + + void RegisterElement (Element element) + { + } + + void WriteElementHtml (Element element, HttpListenerResponse response) + { + response.StatusCode = 200; + using (var s = response.OutputStream) { + using (var w = new StreamWriter (s, Encoding.UTF8)) { + w.WriteLine ($"Hello {element}"); + } + } + response.Close (); + } + async void ProcessWebSocketRequest (HttpListenerContext listenerContext, CancellationToken token) { WebSocketContext webSocketContext = null; try { - webSocketContext = await listenerContext.AcceptWebSocketAsync(subProtocol: null); + webSocketContext = await listenerContext.AcceptWebSocketAsync(subProtocol: null).ConfigureAwait (false); Console.WriteLine ("Accepted WebSocket: {0}", webSocketContext); } catch (Exception e) { @@ -58,26 +107,26 @@ namespace Ooui var receiveResult = await webSocket.ReceiveAsync(new ArraySegment(receiveBuffer), token); if (receiveResult.MessageType == WebSocketMessageType.Close) { - await webSocket.CloseAsync (WebSocketCloseStatus.NormalClosure, "", token); + await webSocket.CloseAsync (WebSocketCloseStatus.NormalClosure, "", token).ConfigureAwait (false); } else if (receiveResult.MessageType == WebSocketMessageType.Binary) { - await webSocket.CloseAsync (WebSocketCloseStatus.InvalidMessageType, "Cannot accept binary frame", token); + await webSocket.CloseAsync (WebSocketCloseStatus.InvalidMessageType, "Cannot accept binary frame", token).ConfigureAwait (false); } else { var size = receiveResult.Count; while (!receiveResult.EndOfMessage) { if (size >= receiveBuffer.Length) { - await webSocket.CloseAsync (WebSocketCloseStatus.MessageTooBig, "Message too big", token); + await webSocket.CloseAsync (WebSocketCloseStatus.MessageTooBig, "Message too big", token).ConfigureAwait (false); return; } - receiveResult = await webSocket.ReceiveAsync (new ArraySegment(receiveBuffer, size, receiveBuffer.Length - size), token); + receiveResult = await webSocket.ReceiveAsync (new ArraySegment(receiveBuffer, size, receiveBuffer.Length - size), token).ConfigureAwait (false); size += receiveResult.Count; } var receivedString = Encoding.UTF8.GetString (receiveBuffer, 0, size); Console.WriteLine ("RECEIVED: {0}", receivedString); var outputBuffer = new ArraySegment (Encoding.UTF8.GetBytes ($"You said: {receivedString}")); - await webSocket.SendAsync (outputBuffer, WebSocketMessageType.Text, true, token); + await webSocket.SendAsync (outputBuffer, WebSocketMessageType.Text, true, token).ConfigureAwait (false); } } } diff --git a/Samples/Program.cs b/Samples/Program.cs index 537ad19..ea4862e 100644 --- a/Samples/Program.cs +++ b/Samples/Program.cs @@ -9,6 +9,8 @@ namespace Samples { Console.WriteLine ("Hello World!"); var server = new Server (); + var button = new Button(); + server.Publish ("/button", button); server.RunAsync ("http://*:8080/").Wait (); return 0; }