Fix returning to pages without re-requesting them
Chrome likes to cache HTML and was making a new web socket request without first requesting a new page. The server however expires a web socket url after its first use. To fix this, web socket urls have a rolling cache policy and can be reconnected to. Fixes #52
This commit is contained in:
parent
0ff69fd3b7
commit
f05f232d5b
|
@ -13,19 +13,19 @@ namespace Ooui.AspNetCore
|
||||||
|
|
||||||
public static TimeSpan SessionTimeout { get; set; } = TimeSpan.FromMinutes (5);
|
public static TimeSpan SessionTimeout { get; set; } = TimeSpan.FromMinutes (5);
|
||||||
|
|
||||||
static readonly ConcurrentDictionary<string, PendingSession> pendingSessions =
|
static readonly ConcurrentDictionary<string, ActiveSession> activeSessions =
|
||||||
new ConcurrentDictionary<string, PendingSession> ();
|
new ConcurrentDictionary<string, ActiveSession> ();
|
||||||
|
|
||||||
public static string BeginSession (HttpContext context, Element element)
|
public static string BeginSession (HttpContext context, Element element)
|
||||||
{
|
{
|
||||||
var id = Guid.NewGuid ().ToString ("N");
|
var id = Guid.NewGuid ().ToString ("N");
|
||||||
|
|
||||||
var s = new PendingSession {
|
var s = new ActiveSession {
|
||||||
Element = element,
|
Element = element,
|
||||||
RequestTimeUtc = DateTime.UtcNow,
|
LastConnectTimeUtc = DateTime.UtcNow,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!pendingSessions.TryAdd (id, s)) {
|
if (!activeSessions.TryAdd (id, s)) {
|
||||||
throw new Exception ("Failed to schedule pending session");
|
throw new Exception ("Failed to schedule pending session");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,20 +60,21 @@ namespace Ooui.AspNetCore
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find the pending session
|
// Clear old sessions
|
||||||
//
|
//
|
||||||
if (!pendingSessions.TryRemove (id, out var pendingSession)) {
|
var toClear = activeSessions.Where (x => (DateTime.UtcNow - x.Value.LastConnectTimeUtc) > SessionTimeout).ToList ();
|
||||||
BadRequest ("Unknown `id`");
|
foreach (var c in toClear) {
|
||||||
return;
|
activeSessions.TryRemove (c.Key, out var _);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reject the session if it's old
|
// Find the pending session
|
||||||
//
|
//
|
||||||
if ((DateTime.UtcNow - pendingSession.RequestTimeUtc) > SessionTimeout) {
|
if (!activeSessions.TryGetValue (id, out var activeSession)) {
|
||||||
BadRequest ("Old `id`");
|
BadRequest ("Unknown `id`");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
activeSession.LastConnectTimeUtc = DateTime.UtcNow;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set the element's dimensions
|
// Set the element's dimensions
|
||||||
|
@ -97,14 +98,14 @@ namespace Ooui.AspNetCore
|
||||||
//
|
//
|
||||||
var token = CancellationToken.None;
|
var token = CancellationToken.None;
|
||||||
var webSocket = await context.WebSockets.AcceptWebSocketAsync ("ooui");
|
var webSocket = await context.WebSockets.AcceptWebSocketAsync ("ooui");
|
||||||
var session = new Ooui.UI.Session (webSocket, pendingSession.Element, w, h, token);
|
var session = new Ooui.UI.Session (webSocket, activeSession.Element, w, h, token);
|
||||||
await session.RunAsync ().ConfigureAwait (false);
|
await session.RunAsync ().ConfigureAwait (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PendingSession
|
class ActiveSession
|
||||||
{
|
{
|
||||||
public Element Element;
|
public Element Element;
|
||||||
public DateTime RequestTimeUtc;
|
public DateTime LastConnectTimeUtc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ function getSize () {
|
||||||
|
|
||||||
// Main entrypoint
|
// Main entrypoint
|
||||||
function ooui (rootElementPath) {
|
function ooui (rootElementPath) {
|
||||||
var opened = false;
|
|
||||||
|
|
||||||
var initialSize = getSize ();
|
var initialSize = getSize ();
|
||||||
var wsArgs = (rootElementPath.indexOf("?") >= 0 ? "&" : "?") +
|
var wsArgs = (rootElementPath.indexOf("?") >= 0 ? "&" : "?") +
|
||||||
|
@ -47,11 +46,11 @@ function ooui (rootElementPath) {
|
||||||
if (location.protocol == "https:") {
|
if (location.protocol == "https:") {
|
||||||
proto = "wss";
|
proto = "wss";
|
||||||
}
|
}
|
||||||
|
|
||||||
socket = new WebSocket (proto + "://" + document.location.host + rootElementPath + wsArgs, "ooui");
|
socket = new WebSocket (proto + "://" + document.location.host + rootElementPath + wsArgs, "ooui");
|
||||||
|
|
||||||
socket.addEventListener ("open", function (event) {
|
socket.addEventListener ("open", function (event) {
|
||||||
console.log ("Web socket opened");
|
console.log ("Web socket opened");
|
||||||
opened = true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.addEventListener ("error", function (event) {
|
socket.addEventListener ("error", function (event) {
|
||||||
|
@ -60,10 +59,6 @@ function ooui (rootElementPath) {
|
||||||
|
|
||||||
socket.addEventListener ("close", function (event) {
|
socket.addEventListener ("close", function (event) {
|
||||||
console.error ("Web socket close", event);
|
console.error ("Web socket close", event);
|
||||||
if (opened) {
|
|
||||||
alert ("Connection to the server has been lost. Please try refreshing the page.");
|
|
||||||
opened = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.addEventListener("message", function (event) {
|
socket.addEventListener("message", function (event) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<h1>Ooui</h1>
|
<h1>Ooui</h1>
|
||||||
<p>Write interactive web apps in C# and F#</p>
|
<p>Write interactive web apps in C# and F#</p>
|
||||||
|
<p><a href="https://github.com/praeclarum/Ooui">Source Code</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue