namespace WatsonTcp
{
using System;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
///
/// Client metadata.
///
public class ClientMetadata : IDisposable
{
#region Public-Members
///
/// GUID.
///
public Guid Guid { get; set; } = Guid.NewGuid();
///
/// IP:port for the connection.
///
public string IpPort
{
get
{
return _IpPort;
}
}
///
/// Name for the client, managed by the developer (you).
///
public string Name { get; set; } = null;
///
/// Metadata for the client, managed by the developer (you).
///
public object Metadata { get; set; } = null;
#endregion
#region Internal-Members
internal TcpClient TcpClient
{
get
{
return _TcpClient;
}
}
internal NetworkStream NetworkStream
{
get
{
return _NetworkStream;
}
set
{
_NetworkStream = value;
if (_NetworkStream != null)
{
_DataStream = _NetworkStream;
}
}
}
internal SslStream SslStream
{
get
{
return _SslStream;
}
set
{
_SslStream = value;
if (_SslStream != null)
{
_DataStream = _SslStream;
}
}
}
internal Stream DataStream
{
get
{
return _DataStream;
}
}
internal byte[] SendBuffer { get; set; } = new byte[65536];
internal Task DataReceiver { get; set; } = null;
internal SemaphoreSlim WriteLock = new SemaphoreSlim(1, 1);
internal SemaphoreSlim ReadLock = new SemaphoreSlim(1, 1);
internal CancellationTokenSource TokenSource = new CancellationTokenSource();
internal CancellationToken Token;
#endregion
#region Private-Members
private TcpClient _TcpClient = null;
private NetworkStream _NetworkStream = null;
private SslStream _SslStream = null;
private Stream _DataStream = null;
private string _IpPort = null;
#endregion
#region Constructors-and-Factories
internal ClientMetadata(TcpClient tcp)
{
_TcpClient = tcp ?? throw new ArgumentNullException(nameof(tcp));
_IpPort = tcp.Client.RemoteEndPoint.ToString();
NetworkStream = tcp.GetStream();
Token = TokenSource.Token;
}
#endregion
#region Public-Methods
///
/// Tear down the object and dispose of resources.
///
public void Dispose()
{
if (TokenSource != null)
{
if (!TokenSource.IsCancellationRequested)
{
TokenSource.Cancel();
TokenSource.Dispose();
}
}
_SslStream?.Close();
_NetworkStream?.Close();
if (_TcpClient != null)
{
_TcpClient.Close();
_TcpClient.Dispose();
}
while (DataReceiver?.Status == TaskStatus.Running)
{
Task.Delay(30).Wait();
}
}
///
/// Human-readable representation of the object.
///
///
public override string ToString()
{
string ret = "[";
ret += Guid.ToString() + "|" + IpPort;
if (!String.IsNullOrEmpty(Name)) ret += "|" + Name;
ret += "]";
return ret;
}
#endregion
#region Private-Methods
#endregion
}
}