Working on "Join Game" feature.
This commit is contained in:
@@ -9,82 +9,89 @@ namespace Shogi.UI.Shared;
|
||||
|
||||
public class ShogiSocket : IDisposable
|
||||
{
|
||||
public event EventHandler<SessionCreatedSocketMessage>? OnCreateGameMessage;
|
||||
public event EventHandler<SessionCreatedSocketMessage>? OnCreateGameMessage;
|
||||
|
||||
private readonly ClientWebSocket socket;
|
||||
private readonly JsonSerializerOptions serializerOptions;
|
||||
private readonly UriBuilder uriBuilder;
|
||||
private readonly CancellationTokenSource cancelToken;
|
||||
private readonly IMemoryOwner<byte> memoryOwner;
|
||||
private bool disposedValue;
|
||||
private readonly ClientWebSocket socket;
|
||||
private readonly JsonSerializerOptions serializerOptions;
|
||||
private readonly UriBuilder uriBuilder;
|
||||
private readonly CancellationTokenSource cancelToken;
|
||||
private readonly IMemoryOwner<byte> memoryOwner;
|
||||
private bool disposedValue;
|
||||
|
||||
public ShogiSocket(IConfiguration configuration, ClientWebSocket socket, JsonSerializerOptions serializerOptions)
|
||||
{
|
||||
this.socket = socket;
|
||||
this.serializerOptions = serializerOptions;
|
||||
this.uriBuilder = new UriBuilder(configuration["SocketUrl"]);
|
||||
this.cancelToken = new CancellationTokenSource();
|
||||
this.memoryOwner = MemoryPool<byte>.Shared.Rent(1024 * 2);
|
||||
}
|
||||
public ShogiSocket(IConfiguration configuration, ClientWebSocket socket, JsonSerializerOptions serializerOptions)
|
||||
{
|
||||
this.socket = socket;
|
||||
this.serializerOptions = serializerOptions;
|
||||
this.uriBuilder = new UriBuilder(configuration["SocketUrl"] ?? throw new InvalidOperationException("SocketUrl configuration is missing."));
|
||||
this.cancelToken = new CancellationTokenSource();
|
||||
this.memoryOwner = MemoryPool<byte>.Shared.Rent(1024 * 2);
|
||||
}
|
||||
|
||||
public async Task OpenAsync(string token)
|
||||
{
|
||||
uriBuilder.Query = new QueryBuilder
|
||||
public async Task OpenAsync(string token)
|
||||
{
|
||||
uriBuilder.Query = new QueryBuilder
|
||||
{
|
||||
{ "token", token }
|
||||
}.ToQueryString().Value;
|
||||
|
||||
await socket.ConnectAsync(this.uriBuilder.Uri, cancelToken.Token);
|
||||
Console.WriteLine("CONNECTED");
|
||||
Listen();
|
||||
}
|
||||
|
||||
private async void Listen()
|
||||
{
|
||||
while (socket.State == WebSocketState.Open && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
var result = await socket.ReceiveAsync(this.memoryOwner.Memory, cancelToken.Token);
|
||||
var memory = this.memoryOwner.Memory[..result.Count].ToArray();
|
||||
var action = JsonDocument
|
||||
.Parse(memory[..result.Count])
|
||||
.RootElement
|
||||
.GetProperty(nameof(ISocketResponse.Action))
|
||||
.Deserialize<SocketAction>();
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case SocketAction.SessionCreated:
|
||||
Console.WriteLine("Session created event.");
|
||||
this.OnCreateGameMessage?.Invoke(this, JsonSerializer.Deserialize<SessionCreatedSocketMessage>(memory, this.serializerOptions)!);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
await socket.ConnectAsync(this.uriBuilder.Uri, cancelToken.Token);
|
||||
Console.WriteLine("Socket Connected");
|
||||
// Fire and forget! I'm way too lazy to write my own javascript interop to a web worker. Nooo thanks.
|
||||
var listening = Listen().ContinueWith(antecedent =>
|
||||
{
|
||||
if (antecedent.Exception != null)
|
||||
{
|
||||
throw antecedent.Exception;
|
||||
}
|
||||
}, TaskContinuationOptions.OnlyOnFaulted);
|
||||
}
|
||||
if (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
throw new InvalidOperationException("Stopped socket listening without cancelling.");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
private async Task Listen()
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
cancelToken.Cancel();
|
||||
socket.Dispose();
|
||||
memoryOwner.Dispose();
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
while (socket.State == WebSocketState.Open && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
var result = await socket.ReceiveAsync(this.memoryOwner.Memory, cancelToken.Token);
|
||||
var memory = this.memoryOwner.Memory[..result.Count].ToArray();
|
||||
var action = JsonDocument
|
||||
.Parse(memory[..result.Count])
|
||||
.RootElement
|
||||
.GetProperty(nameof(ISocketResponse.Action))
|
||||
.Deserialize<SocketAction>();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
switch (action)
|
||||
{
|
||||
case SocketAction.SessionCreated:
|
||||
Console.WriteLine("Session created event.");
|
||||
this.OnCreateGameMessage?.Invoke(this, JsonSerializer.Deserialize<SessionCreatedSocketMessage>(memory, this.serializerOptions)!);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
throw new InvalidOperationException("Stopped socket listening without cancelling.");
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
cancelToken.Cancel();
|
||||
socket.Dispose();
|
||||
memoryOwner.Dispose();
|
||||
}
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user