diff --git a/Ooui.AspNetCore/ElementResult.cs b/Ooui.AspNetCore/ElementResult.cs index 03f9975..4c1f0fe 100644 --- a/Ooui.AspNetCore/ElementResult.cs +++ b/Ooui.AspNetCore/ElementResult.cs @@ -10,11 +10,13 @@ namespace Ooui.AspNetCore { readonly Element element; readonly string title; + readonly bool disposeWhenDone; - public ElementResult (Element element, string title = "") + public ElementResult (Element element, string title = "", bool disposeWhenDone = true) { this.element = element; this.title = title; + this.disposeWhenDone = disposeWhenDone; } public override async Task ExecuteResultAsync (ActionContext context) @@ -29,7 +31,7 @@ namespace Ooui.AspNetCore element.Style.Height = GetCookieDouble (context.HttpContext.Request.Cookies, "oouiWindowHeight", 24, 480, 10000); } - var sessionId = WebSocketHandler.BeginSession (context.HttpContext, element); + var sessionId = WebSocketHandler.BeginSession (context.HttpContext, element, disposeWhenDone); var initialHtml = element.OuterHtml; var html = UI.RenderTemplate (WebSocketHandler.WebSocketPath + "?id=" + sessionId, title: title, initialHtml: initialHtml); var htmlBytes = Encoding.UTF8.GetBytes (html); diff --git a/Ooui.AspNetCore/WebSocketHandler.cs b/Ooui.AspNetCore/WebSocketHandler.cs index 03a7794..f43ae73 100644 --- a/Ooui.AspNetCore/WebSocketHandler.cs +++ b/Ooui.AspNetCore/WebSocketHandler.cs @@ -16,13 +16,14 @@ namespace Ooui.AspNetCore static readonly ConcurrentDictionary pendingSessions = new ConcurrentDictionary (); - public static string BeginSession (HttpContext context, Element element) + public static string BeginSession (HttpContext context, Element element, bool disposeElementWhenDone) { var id = Guid.NewGuid ().ToString ("N"); var s = new PendingSession { Element = element, CreateTimeUtc = DateTime.UtcNow, + DisposeElementWhenDone = disposeElementWhenDone, }; if (!pendingSessions.TryAdd (id, s)) { @@ -97,7 +98,7 @@ namespace Ooui.AspNetCore // var token = CancellationToken.None; var webSocket = await context.WebSockets.AcceptWebSocketAsync ("ooui"); - var session = new Ooui.WebSocketSession (webSocket, activeSession.Element, w, h, token); + var session = new Ooui.WebSocketSession (webSocket, activeSession.Element, activeSession.DisposeElementWhenDone, w, h, token); await session.RunAsync ().ConfigureAwait (false); } @@ -105,6 +106,7 @@ namespace Ooui.AspNetCore { public Element Element; public DateTime CreateTimeUtc; + public bool DisposeElementWhenDone; } } } diff --git a/Ooui/UI.cs b/Ooui/UI.cs index a66ff59..395c817 100644 --- a/Ooui/UI.cs +++ b/Ooui/UI.cs @@ -95,14 +95,14 @@ namespace Ooui Start (); } - public static void Publish (string path, Func elementCtor) + public static void Publish (string path, Func elementCtor, bool disposeElementWhenDone = true) { - Publish (path, new ElementHandler (elementCtor)); + Publish (path, new ElementHandler (elementCtor, disposeElementWhenDone)); } - public static void Publish (string path, Element element) + public static void Publish (string path, Element element, bool disposeElementWhenDone = true) { - Publish (path, () => element); + Publish (path, () => element, disposeElementWhenDone); } public static void PublishFile (string filePath) @@ -334,9 +334,12 @@ namespace Ooui { readonly Lazy element; - public ElementHandler (Func ctor) + public bool DisposeElementWhenDone { get; } + + public ElementHandler (Func ctor, bool disposeElementWhenDone) { element = new Lazy (ctor); + DisposeElementWhenDone = disposeElementWhenDone; } public Element GetElement () => element.Value; @@ -513,8 +516,10 @@ namespace Ooui } Element element = null; + bool disposeElementWhenDone = true; try { element = elementHandler.GetElement (); + disposeElementWhenDone = elementHandler.DisposeElementWhenDone; if (element == null) throw new Exception ("Handler returned a null element"); @@ -568,7 +573,7 @@ namespace Ooui // Create a new session and let it handle everything from here // try { - var session = new WebSocketSession (webSocket, element, w, h, serverToken); + var session = new WebSocketSession (webSocket, element, disposeElementWhenDone, w, h, serverToken); await session.RunAsync ().ConfigureAwait (false); } catch (System.Net.WebSockets.WebSocketException ex) when (ex.WebSocketErrorCode == System.Net.WebSockets.WebSocketError.ConnectionClosedPrematurely) { @@ -599,8 +604,10 @@ namespace Ooui lock (publishedPaths) { publishedPaths.TryGetValue (elementPath, out handler); } + var disposeElementWhenDone = true; if (handler is ElementHandler eh) { element = eh.GetElement (); + disposeElementWhenDone = eh.DisposeElementWhenDone; } else { element = new Div (); @@ -609,7 +616,7 @@ namespace Ooui var ops = initialSize.Split (' '); var initialWidth = double.Parse (ops[0]); var initialHeight = double.Parse (ops[1]); - var g = new WebAssemblySession (sessionId, element, initialWidth, initialHeight); + var g = new WebAssemblySession (sessionId, element, disposeElementWhenDone, initialWidth, initialHeight); lock (globalElementSessions) { globalElementSessions[sessionId] = g; } diff --git a/Ooui/WebAssemblySession.cs b/Ooui/WebAssemblySession.cs index b7d53f4..fbe722d 100644 --- a/Ooui/WebAssemblySession.cs +++ b/Ooui/WebAssemblySession.cs @@ -9,7 +9,7 @@ namespace Ooui readonly string id; readonly Action handleElementMessageSent; - public WebAssemblySession (string id, Element element, double initialWidth, double initialHeight) + public WebAssemblySession (string id, Element element, bool disposeElementWhenDone, double initialWidth, double initialHeight) : base (element, initialWidth, initialHeight) { this.id = id; diff --git a/Ooui/WebSocketSession.cs b/Ooui/WebSocketSession.cs index 7b40e4d..b18a82c 100644 --- a/Ooui/WebSocketSession.cs +++ b/Ooui/WebSocketSession.cs @@ -23,7 +23,7 @@ namespace Ooui DateTime lastTransmitTime = DateTime.MinValue; readonly TimeSpan throttleInterval = TimeSpan.FromSeconds (1.0 / UI.MaxFps); - public WebSocketSession (WebSocket webSocket, Element element, double initialWidth, double initialHeight, CancellationToken serverToken) + public WebSocketSession (WebSocket webSocket, Element element, bool disposeElementWhenDone, double initialWidth, double initialHeight, CancellationToken serverToken) : base (element, initialWidth, initialHeight) { this.webSocket = webSocket;