?
This commit is contained in:
106
Relay/ActiveClient.cs
Normal file
106
Relay/ActiveClient.cs
Normal file
@@ -0,0 +1,106 @@
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using CatLink.Models;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace CatLink.Relay
|
||||
{
|
||||
public class ActiveClient
|
||||
{
|
||||
private readonly ILogger<ActiveClient> _logger;
|
||||
private readonly Socket _socket;
|
||||
private readonly StreamReader _reader;
|
||||
private readonly StreamWriter _writer;
|
||||
private readonly object _writeLock = new();
|
||||
private readonly Thread _thread;
|
||||
private readonly Action<ActiveClient, Msg> _messageHandler;
|
||||
private readonly Action<ActiveClient> _disconnectHandler;
|
||||
|
||||
public string ClientKey { get; }
|
||||
public uint StubIp { get; }
|
||||
public Dictionary<int, uint> TcpStreams { get; } = new();
|
||||
public HashSet<int> PendingStreams { get; } = new();
|
||||
public long LastHeartbeat { get; set; }
|
||||
|
||||
public ActiveClient(
|
||||
string clientKey,
|
||||
uint stubIp,
|
||||
Socket socket,
|
||||
Action<ActiveClient, Msg> messageHandler,
|
||||
Action<ActiveClient> disconnectHandler,
|
||||
ILogger<ActiveClient> logger)
|
||||
{
|
||||
ClientKey = clientKey;
|
||||
StubIp = stubIp;
|
||||
_socket = socket;
|
||||
_messageHandler = messageHandler;
|
||||
_disconnectHandler = disconnectHandler;
|
||||
_logger = logger;
|
||||
|
||||
var stream = new NetworkStream(socket);
|
||||
_reader = new StreamReader(stream, Encoding.UTF8);
|
||||
_writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
|
||||
|
||||
LastHeartbeat = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
|
||||
_thread = new Thread(HandleMessages)
|
||||
{
|
||||
IsBackground = true
|
||||
};
|
||||
_thread.Start();
|
||||
}
|
||||
|
||||
private void HandleMessages()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (_socket.Connected)
|
||||
{
|
||||
var line = _reader.ReadLine();
|
||||
if (line == null) break;
|
||||
|
||||
var msg = Msg.FromString(line);
|
||||
_messageHandler(this, msg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error handling messages for client {ClientKey}", ClientKey);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_disconnectHandler(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Send(Msg msg)
|
||||
{
|
||||
lock (_writeLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
_writer.WriteLine(msg.ToString());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error sending message to client {ClientKey}", ClientKey);
|
||||
Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
_socket.Close();
|
||||
_reader.Dispose();
|
||||
_writer.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error disconnecting client {ClientKey}", ClientKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user