diff --git a/Client/Components/App.razor b/Client/Components/App.razor
index 5dac545..3fde3ff 100644
--- a/Client/Components/App.razor
+++ b/Client/Components/App.razor
@@ -1,4 +1,7 @@
-
+@using Microsoft.Extensions.Configuration
+@inject IConfiguration Configuration
+
+
@@ -19,6 +22,44 @@
+
\ No newline at end of file
diff --git a/Client/Components/Pages/Home.razor b/Client/Components/Pages/Home.razor
index cfa1177..d07d89c 100644
--- a/Client/Components/Pages/Home.razor
+++ b/Client/Components/Pages/Home.razor
@@ -7,6 +7,7 @@
Replay viewer
Replay browser for Space Station 14
+There is currently 1 user here.
diff --git a/Client/Components/Pages/Search.razor b/Client/Components/Pages/Search.razor
index aaf70d9..7091a38 100644
--- a/Client/Components/Pages/Search.razor
+++ b/Client/Components/Pages/Search.razor
@@ -8,6 +8,7 @@
Replay viewer
Replay browser for Space Station 14
+There is currently 1 user here.
Search for replays by using the search bar below
Back to main page
diff --git a/Server/Api/DataController.cs b/Server/Api/DataController.cs
index 09c750f..6734c71 100644
--- a/Server/Api/DataController.cs
+++ b/Server/Api/DataController.cs
@@ -1,6 +1,11 @@
-using Microsoft.AspNetCore.Cors;
+using System.Collections.Concurrent;
+using System.Net.WebSockets;
+using System.Text;
+using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
+using Serilog;
+using Shared;
namespace Server.Api;
@@ -13,10 +18,13 @@ namespace Server.Api;
public class DataController : ControllerBase
{
private readonly ReplayDbContext _context;
-
+ public static readonly Dictionary ConnectedUsers = new();
+ private Timer _timer;
+
public DataController(ReplayDbContext context)
{
_context = context;
+ _timer = new Timer(CheckInactiveConnections, null, TimeSpan.Zero, TimeSpan.FromSeconds(5));
}
///
@@ -39,4 +47,55 @@ [FromQuery] string username
return Ok(completions);
}
+
+ [Route("/ws")]
+ public async Task Connect()
+ {
+ if (HttpContext.WebSockets.IsWebSocketRequest)
+ {
+ var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync();
+ var userId = Guid.NewGuid();
+ ConnectedUsers.Add(userId, webSocket);
+ Log.Information("User connected with ID {UserId}", userId);
+ await Echo(webSocket, userId);
+ }
+ else
+ {
+ HttpContext.Response.StatusCode = 400;
+ }
+ }
+
+ private async Task Echo(WebSocket webSocket, Guid userId)
+ {
+ var buffer = new byte[1024 * 4];
+ var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None);
+
+ while (!result.CloseStatus.HasValue)
+ {
+ result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None);
+
+ if (Encoding.UTF8.GetString(buffer).Contains("count"))
+ {
+ var count = ConnectedUsers.Count;
+ var countBytes = Encoding.UTF8.GetBytes(count.ToString());
+ await webSocket.SendAsync(new ArraySegment(countBytes), WebSocketMessageType.Text, true, CancellationToken.None);
+ }
+
+ buffer = new byte[1024 * 4];
+ }
+
+ ConnectedUsers.Remove(userId, out _);
+ await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
+ }
+
+ private void CheckInactiveConnections(object state)
+ {
+ foreach (var user in ConnectedUsers)
+ {
+ if (user.Value.State == WebSocketState.Open) continue;
+
+ ConnectedUsers.Remove(user.Key, out _);
+ Log.Information("User disconnected with ID {UserId}", user.Key);
+ }
+ }
}
\ No newline at end of file
diff --git a/Server/Program.cs b/Server/Program.cs
index 791b89e..e6b6bf6 100644
--- a/Server/Program.cs
+++ b/Server/Program.cs
@@ -66,6 +66,13 @@
builder.Services.AddMvc();
var app = builder.Build();
+
+ var webSocketOptions = new WebSocketOptions()
+ {
+ KeepAliveInterval = TimeSpan.FromSeconds(10),
+ };
+
+ app.UseWebSockets(webSocketOptions);
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())