Reconnection does not work now, but part of deep reconnection logic written

This commit is contained in:
2025-04-08 13:08:29 +03:00
parent 95dbf63511
commit 24bd06b3d0
3 changed files with 65 additions and 15 deletions
+1 -1
View File
@@ -58,7 +58,7 @@ class Program
Console.WriteLine("Printer created"); Console.WriteLine("Printer created");
Thread.Sleep(100); Thread.Sleep(100);
// frontendBridge.Obstacle(); frontendBridge.Obstacle();
var name = disposingPrinter.GetName(); var name = disposingPrinter.GetName();
DemoCheck.BasicNonParamsCall = true; DemoCheck.BasicNonParamsCall = true;
Console.WriteLine("Printer name : {0}", name); Console.WriteLine("Printer name : {0}", name);
@@ -4,6 +4,7 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using mROA.Abstract; using mROA.Abstract;
using static System.Byte;
namespace mROA.Implementation.Backend namespace mROA.Implementation.Backend
{ {
@@ -66,7 +67,7 @@ namespace mROA.Implementation.Backend
while (true) while (true)
{ {
var client = _tcpListener.AcceptTcpClient(); var client = _tcpListener.AcceptTcpClient();
Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}"); Console.WriteLine($"Client connected from {client.Client.RemoteEndPoint}");
var interaction = Activator.CreateInstance(_interactionModuleType!) as INextGenerationInteractionModule; var interaction = Activator.CreateInstance(_interactionModuleType!) as INextGenerationInteractionModule;
foreach (var injectableModule in _injectableModules!) foreach (var injectableModule in _injectableModules!)
@@ -75,7 +76,7 @@ namespace mROA.Implementation.Backend
interaction!.Inject(_serialization); interaction!.Inject(_serialization);
interaction.BaseStream = client.GetStream(); interaction.BaseStream = client.GetStream();
var connectionRequest = interaction.GetNextMessageReceiving().GetAwaiter().GetResult()!; var connectionRequest = interaction.GetNextMessageReceiving().GetAwaiter().GetResult()!;
switch (connectionRequest.MessageType) switch (connectionRequest.MessageType)
@@ -91,6 +92,8 @@ namespace mROA.Implementation.Backend
var recoveryRequest = _serialization!.Deserialize<ClientRecovery>(connectionRequest.Data)!; var recoveryRequest = _serialization!.Deserialize<ClientRecovery>(connectionRequest.Data)!;
var recoveryInteraction = _hub.GetInteraction(recoveryRequest.Id); var recoveryInteraction = _hub.GetInteraction(recoveryRequest.Id);
recoveryInteraction.BaseStream = client.GetStream(); recoveryInteraction.BaseStream = client.GetStream();
recoveryInteraction.Restart(false); recoveryInteraction.Restart(false);
Console.WriteLine($"Client {recoveryRequest.Id} reconnected"); Console.WriteLine($"Client {recoveryRequest.Id} reconnected");
break; break;
@@ -17,15 +17,13 @@ namespace mROA.Implementation
private Task<NetworkMessageHeader>? _currentReceiving; private Task<NetworkMessageHeader>? _currentReceiving;
private ISerializationToolkit? _serialization; private ISerializationToolkit? _serialization;
private Stream? _baseStream; private Stream? _baseStream;
private bool _isRecovering; private bool _isConnected = true;
private event Action OnReconnected; private bool _isInReconnectionState;
private TaskCompletionSource<Stream> _reconnection;
private TaskCompletionSource<Stream> _reconection;
public NextGenerationInteractionModule() public NextGenerationInteractionModule()
{ {
_reconection = new TaskCompletionSource<Stream>(); _reconnection = new TaskCompletionSource<Stream>();
_reconection.SetResult(Stream.Null);
} }
public int ConnectionId { get; set; } public int ConnectionId { get; set; }
@@ -104,6 +102,8 @@ namespace mROA.Implementation
if (await PostMessageInternal(messageHeader)) if (await PostMessageInternal(messageHeader))
break; break;
_isConnected = false;
await MakeRecovery("OUT");
// Console.WriteLine("Try to get lock from post"); // Console.WriteLine("Try to get lock from post");
// lock (_reconection) // lock (_reconection)
// { // {
@@ -159,8 +159,9 @@ namespace mROA.Implementation
{ {
return await Receive(); return await Receive();
} }
catch (Exception) catch (Exception ex)
{ {
await MakeRecovery("IN");
// Console.WriteLine("Try to get lock from receive"); // Console.WriteLine("Try to get lock from receive");
// lock (_reconection) // lock (_reconection)
// { // {
@@ -186,10 +187,18 @@ namespace mROA.Implementation
private ushort ReadMessageLength() private ushort ReadMessageLength()
{ {
var firstBit = (byte)BaseStream.ReadByte();
var firstBit = BaseStream.ReadByte();
if (firstBit == -1)
{
_isConnected = false;
throw new EndOfStreamException();
}
_isConnected = true;
var secondBit = (byte)BaseStream.ReadByte(); var secondBit = (byte)BaseStream.ReadByte();
var len = BitConverter.ToUInt16(new[] { firstBit, secondBit }); var len = BitConverter.ToUInt16(new[] { (byte)firstBit, secondBit });
return len; return len;
} }
@@ -216,12 +225,50 @@ namespace mROA.Implementation
public async Task Restart(bool sendRecovery) public async Task Restart(bool sendRecovery)
{ {
if (sendRecovery) if (sendRecovery)
{
await PostMessageAsync( await PostMessageAsync(
new NetworkMessageHeader(_serialization!, new ClientRecovery(Math.Abs(ConnectionId)))); new NetworkMessageHeader(_serialization!, new ClientRecovery(Math.Abs(ConnectionId))));
_isRecovering = false;
_reconection.SetResult(BaseStream!); var confirmByte = BaseStream.ReadByte();
_reconection = new TaskCompletionSource<Stream>(); Console.WriteLine("Reconnection byte {0}", confirmByte);
}
else
{
BaseStream.WriteByte(byte.MaxValue);
}
Console.WriteLine("Setting result for reconnection");
_reconnection.SetResult(BaseStream!);
Console.WriteLine("Set result for reconnection successfull");
_reconnection = new TaskCompletionSource<Stream>();
}
private async Task MakeRecovery(string source)
{
Console.WriteLine("Staring recovery from {0}", source);
lock (_reconnection)
{
Console.WriteLine("Got lock from {0}", source);
if (_isConnected || _isInReconnectionState)
{
Console.WriteLine($"{_isConnected} {_isInReconnectionState} {!_baseStream.CanRead} {!_baseStream.CanWrite}");
return;
}
Console.WriteLine("Call OnDisconnected from {0}", source);
_isInReconnectionState = true;
OnDisconected?.Invoke(ConnectionId);
}
Console.WriteLine("Waiting for reconnect from {0}", source);
await _reconnection.Task;
Console.WriteLine("Reconnect finished from {0}", source);
lock (_reconnection)
{
_isInReconnectionState = false;
}
} }
} }
} }