2025-02-20 16:10:09 +03:00
|
|
|
using System;
|
2025-02-05 15:05:49 +03:00
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Sockets;
|
2025-04-12 12:44:38 +03:00
|
|
|
using System.Threading.Channels;
|
2025-04-06 20:51:12 +03:00
|
|
|
using System.Threading.Tasks;
|
2025-02-05 15:05:49 +03:00
|
|
|
using mROA.Abstract;
|
2025-03-31 12:27:46 +03:00
|
|
|
using Exception = System.Exception;
|
2025-02-05 15:05:49 +03:00
|
|
|
|
2025-02-20 16:10:09 +03:00
|
|
|
namespace mROA.Implementation.Frontend
|
2025-02-05 15:05:49 +03:00
|
|
|
{
|
2025-02-20 16:10:09 +03:00
|
|
|
public class NetworkFrontendBridge : IFrontendBridge
|
2025-02-05 15:05:49 +03:00
|
|
|
{
|
2025-04-06 21:20:18 +03:00
|
|
|
private readonly IPEndPoint _serverEndPoint;
|
|
|
|
|
private TcpClient _tcpClient = new();
|
2025-04-12 12:44:38 +03:00
|
|
|
private INextGenerationInteractionModule? _interactionModule;
|
2025-02-20 16:10:09 +03:00
|
|
|
private ISerializationToolkit? _serialization;
|
|
|
|
|
|
2025-04-06 21:20:18 +03:00
|
|
|
public NetworkFrontendBridge(IPEndPoint serverEndPoint)
|
2025-02-05 15:05:49 +03:00
|
|
|
{
|
2025-04-06 21:20:18 +03:00
|
|
|
_serverEndPoint = serverEndPoint;
|
2025-02-07 16:53:12 +03:00
|
|
|
}
|
|
|
|
|
|
2025-02-20 16:10:09 +03:00
|
|
|
public void Inject<T>(T dependency)
|
2025-02-13 10:52:06 +03:00
|
|
|
{
|
2025-02-20 16:10:09 +03:00
|
|
|
switch (dependency)
|
|
|
|
|
{
|
|
|
|
|
case NextGenerationInteractionModule interactionModule:
|
|
|
|
|
_interactionModule = interactionModule;
|
|
|
|
|
break;
|
|
|
|
|
case ISerializationToolkit toolkit:
|
|
|
|
|
_serialization = toolkit;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-02-13 10:52:06 +03:00
|
|
|
}
|
|
|
|
|
|
2025-02-20 16:10:09 +03:00
|
|
|
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
|
|
|
|
2025-02-20 16:10:09 +03:00
|
|
|
_interactionModule.BaseStream = _tcpClient.GetStream();
|
2025-04-12 12:44:38 +03:00
|
|
|
_interactionModule.UntrustedReceiveChanel = Channel.CreateUnbounded<NetworkMessageHeader>(new UnboundedChannelOptions
|
2025-04-06 20:51:12 +03:00
|
|
|
{
|
2025-04-12 12:44:38 +03:00
|
|
|
SingleWriter = false,
|
|
|
|
|
SingleReader = false,
|
|
|
|
|
AllowSynchronousContinuations = true
|
|
|
|
|
}).Reader;
|
|
|
|
|
_interactionModule.OnDisconnected += id => { Reconnect(); };
|
|
|
|
|
|
2025-04-09 14:04:04 +03:00
|
|
|
_interactionModule.PostMessageAsync(new NetworkMessageHeader(_serialization, new ClientConnect())).Wait();
|
|
|
|
|
var idMessage = _interactionModule.GetNextMessageReceiving(false).GetAwaiter().GetResult();
|
|
|
|
|
if (idMessage.MessageType != EMessageType.IdAssigning)
|
2025-02-20 16:10:09 +03:00
|
|
|
{
|
2025-03-13 20:01:17 +03:00
|
|
|
throw new Exception(
|
2025-04-09 14:04:04 +03:00
|
|
|
$"Incorrect message type. Must be IdAssigning, current : {idMessage.MessageType.ToString()}");
|
2025-02-20 16:10:09 +03:00
|
|
|
}
|
2025-04-06 20:51:12 +03:00
|
|
|
|
|
|
|
|
|
2025-04-09 14:04:04 +03:00
|
|
|
var assignment = _serialization.Deserialize<IdAssignment>(idMessage.Data)!;
|
2025-03-14 13:15:04 +03:00
|
|
|
_interactionModule.ConnectionId = -assignment.Id;
|
2025-02-24 18:01:34 +03:00
|
|
|
TransmissionConfig.OwnershipRepository = new StaticOwnershipRepository(assignment.Id);
|
2025-02-20 16:10:09 +03:00
|
|
|
}
|
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();
|
2025-04-12 12:44:38 +03:00
|
|
|
_interactionModule.UntrustedReceiveChanel = Channel.CreateUnbounded<NetworkMessageHeader>(new UnboundedChannelOptions
|
|
|
|
|
{
|
|
|
|
|
SingleWriter = false,
|
|
|
|
|
SingleReader = false,
|
|
|
|
|
AllowSynchronousContinuations = true
|
|
|
|
|
}).Reader;
|
2025-04-08 11:48:46 +03:00
|
|
|
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();
|
|
|
|
|
}
|
2025-02-05 15:05:49 +03:00
|
|
|
}
|
|
|
|
|
}
|