Files
mROA/mROA/Implementation/Frontend/NetworkFrontendBridge.cs
T

100 lines
3.5 KiB
C#
Raw Normal View History

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Channels;
2025-04-06 20:51:12 +03:00
using System.Threading.Tasks;
using mROA.Abstract;
using Exception = System.Exception;
namespace mROA.Implementation.Frontend
{
public class NetworkFrontendBridge : IFrontendBridge
{
2025-04-06 21:20:18 +03:00
private readonly IPEndPoint _serverEndPoint;
private TcpClient _tcpClient = new();
private INextGenerationInteractionModule? _interactionModule;
private ISerializationToolkit? _serialization;
2025-04-06 21:20:18 +03:00
public NetworkFrontendBridge(IPEndPoint serverEndPoint)
{
2025-04-06 21:20:18 +03:00
_serverEndPoint = serverEndPoint;
}
public void Inject<T>(T dependency)
{
switch (dependency)
{
case NextGenerationInteractionModule interactionModule:
_interactionModule = interactionModule;
break;
case ISerializationToolkit toolkit:
_serialization = toolkit;
break;
}
}
public void Connect()
{
if (_interactionModule is null)
throw new Exception("Interaction module was not injected");
if (_serialization == null)
throw new NullReferenceException("Serialization toolkit is not initialized");
2025-03-13 20:01:17 +03:00
2025-04-06 21:20:18 +03:00
_tcpClient.Connect(_serverEndPoint);
2025-04-06 20:51:12 +03:00
_interactionModule.BaseStream = _tcpClient.GetStream();
_interactionModule.UntrustedReceiveChanel = Channel.CreateUnbounded<NetworkMessageHeader>(new UnboundedChannelOptions
2025-04-06 20:51:12 +03:00
{
SingleWriter = false,
SingleReader = false,
AllowSynchronousContinuations = true
}).Reader;
_interactionModule.OnDisconnected += id => { Reconnect(); };
_interactionModule.PostMessageAsync(new NetworkMessageHeader(_serialization, new ClientConnect())).Wait();
var idMessage = _interactionModule.GetNextMessageReceiving(false).GetAwaiter().GetResult();
if (idMessage.MessageType != EMessageType.IdAssigning)
{
2025-03-13 20:01:17 +03:00
throw new Exception(
$"Incorrect message type. Must be IdAssigning, current : {idMessage.MessageType.ToString()}");
}
2025-04-06 20:51:12 +03:00
var assignment = _serialization.Deserialize<IdAssignment>(idMessage.Data)!;
_interactionModule.ConnectionId = -assignment.Id;
2025-02-24 18:01:34 +03:00
TransmissionConfig.OwnershipRepository = new StaticOwnershipRepository(assignment.Id);
}
2025-04-06 20:51:12 +03:00
2025-04-06 21:20:18 +03:00
private async Task Reconnect()
2025-04-06 20:51:12 +03:00
{
2025-04-06 21:20:18 +03:00
_tcpClient = new TcpClient();
_tcpClient.Connect(_serverEndPoint);
2025-04-06 20:51:12 +03:00
_interactionModule.BaseStream = _tcpClient.GetStream();
_interactionModule.UntrustedReceiveChanel = Channel.CreateUnbounded<NetworkMessageHeader>(new UnboundedChannelOptions
{
SingleWriter = false,
SingleReader = false,
AllowSynchronousContinuations = true
}).Reader;
await _interactionModule.Restart(true);
2025-04-06 20:51:12 +03:00
}
public void Obstacle()
{
2025-04-08 22:42:00 +03:00
_interactionModule!.BaseStream!.Dispose();
_tcpClient.Dispose();
2025-04-06 20:51:12 +03:00
}
public void Disconnect()
{
_ = _interactionModule!.PostMessageAsync(new NetworkMessageHeader(_serialization!, new ClientDisconnect()));
2025-04-09 14:11:31 +03:00
_interactionModule.Dispose();
2025-04-06 20:51:12 +03:00
_tcpClient.Dispose();
}
public void Dispose()
{
Disconnect();
}
}
}