Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Websocket Changes #86

Merged
merged 1 commit into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Fuyu.Backend.EFT/Controllers/PushNotiferGetWebsocketController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Fuyu.Common.Networking;

namespace Fuyu.Backend.EFT.Controllers
{
public partial class PushNotiferGetWebsocketController : WsController
{
public PushNotiferGetWebsocketController() : base(PathExpression())
{
}

// NOTE: No event registrations as I am not implementing anything
// -- nexus4880, 2024-10-23
public override Task RunAsync(WsContext context)
{
return Task.CompletedTask;
}

[GeneratedRegex("^/push/notifier/getwebsocket/(?<channelId>[A-Za-z0-9]+)$")]
private static partial Regex PathExpression();
}
}
4 changes: 4 additions & 0 deletions Fuyu.Backend.EFT/Servers/EftMainServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public void RegisterServices()
// Custom
HttpRouter.AddController<FuyuGameLoginController>();
HttpRouter.AddController<FuyuGameRegisterController>();

// EFT
HttpRouter.AddController<AccountCustomizationController>();
HttpRouter.AddController<AchievementListController>();
Expand Down Expand Up @@ -69,6 +70,9 @@ public void RegisterServices()
HttpRouter.AddController<SurveyController>();
HttpRouter.AddController<TraderSettingsController>();
HttpRouter.AddController<WeatherController>();

// EFT WS
WsRouter.AddController<PushNotiferGetWebsocketController>();
}
}
}
3 changes: 1 addition & 2 deletions Fuyu.Common/Networking/HttpServer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -82,10 +83,8 @@ private async Task OnWsRequestAsync(HttpListenerContext listenerContext)
try
{
var context = new WsContext(listenerContext.Request, listenerContext.Response, ws);

var time = DateTime.UtcNow.ToString();
Terminal.WriteLine($"[{time}][{Name}][WS ] {context.Path}");

await WsRouter.RouteAsync(context);
}
catch (Exception ex)
Expand Down
51 changes: 35 additions & 16 deletions Fuyu.Common/Networking/WsContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ public class WsContext : WebRouterContext
private const int _bufferSize = 32000;
private readonly WebSocket _ws;

public Func<WsContext, Task> OnCloseAsync;
public Func<WsContext, string, Task> OnTextAsync;
public Func<WsContext, byte[], Task> OnBinaryAsync;
public delegate Task OnTextEventHandler(WsContext sender, string text);
public delegate Task OnBinaryEventHandler(WsContext sender, byte[] binary);
public delegate Task OnCloseEventHandler(WsContext sender);

public event OnTextEventHandler OnTextEvent;
public event OnBinaryEventHandler OnBinaryEvent;
public event OnCloseEventHandler OnCloseEvent;

public WsContext(HttpListenerRequest request, HttpListenerResponse response, WebSocket ws) : base(request, response)
{
Expand All @@ -26,32 +30,43 @@ public bool IsOpen()
return _ws.State == WebSocketState.Open;
}

// TODO:
// * use System.Buffers.ArrayPool for receiveBuffer
// -- seionmoya, 2024/09/09
public async Task ReceiveAsync()
// TODO:
// * use System.Buffers.ArrayPool for receiveBuffer
// -- seionmoya, 2024/09/09

// NOTE: Made this internal because consumers
// shouldn't be calling this on their own
// -- nexus4880, 2024-10-23
internal async Task PollAsync()
{
var buffer = new byte[_bufferSize];
var received = await _ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var received = await _ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var data = new byte[received.Count];
Array.Copy(buffer, 0, data, 0, data.Length);

switch (received.MessageType)
{
case WebSocketMessageType.Close:
await OnCloseAsync(this);
await CloseAsync();
break;

case WebSocketMessageType.Text:
var text = Encoding.UTF8.GetString(data);
await OnTextAsync(this, text);
if (OnTextEvent != null)
{
await OnTextEvent(this, text);
}

break;

case WebSocketMessageType.Binary:
await OnBinaryAsync(this, data);
if (OnBinaryEvent != null)
{
await OnBinaryEvent(this, data);
}

break;
}

case WebSocketMessageType.Close:
await CloseAsync();
break;
}
}

public async Task SendTextAsync(string text)
Expand All @@ -70,6 +85,10 @@ public async Task SendBinaryAsync(byte[] data)
public async Task CloseAsync()
{
await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
if (OnCloseEvent != null)
{
await OnCloseEvent(this);
}
}
}
}
18 changes: 7 additions & 11 deletions Fuyu.Common/Networking/WsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@ protected WsController(string path) : base(path)
// match static paths
}

public virtual Task OnConnectAsync(WsContext context)
{
public override Task RunAsync(WsContext context)
{
context.OnCloseEvent += OnCloseAsync;
context.OnTextEvent += OnTextAsync;
context.OnBinaryEvent += OnBinaryAsync;

return Task.CompletedTask;
}
}

public virtual Task OnCloseAsync(WsContext context)
{
Expand All @@ -34,13 +38,5 @@ public virtual Task OnBinaryAsync(WsContext context, byte[] binary)
{
return Task.CompletedTask;
}

public async Task InitializeAsync(WsContext context)
{
context.OnCloseAsync = OnCloseAsync;
context.OnTextAsync = OnTextAsync;
context.OnBinaryAsync = OnBinaryAsync;
await OnConnectAsync(context);
}
}
}
21 changes: 16 additions & 5 deletions Fuyu.Common/Networking/WsRouter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,22 @@ public WsRouter() : base()
public override async Task RouteAsync(WsContext context)
{
var matches = GetAllMatching(context);
foreach (var match in matches)
var tasks = new Task[matches.Count];
for (var i = 0; i < matches.Count; i++)
{
await match.InitializeAsync(context);
await match.RunAsync(context);
tasks[i] = matches[i].RunAsync(context);
}
}
}

await Task.WhenAll(tasks);

while (context.IsOpen())
{
await context.PollAsync();
}

// NOTE: No need to call context.CloseAsync here
// because ReceiveAsync will handle that for us
// -- nexus4880, 2024-10-23
}
}
}