You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/Network/Utils/ExClientServerCachee.cs

114 lines
4.2 KiB

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
namespace ZeroLevel.Network
{
internal sealed class ExClientServerCachee
: IDisposable
{
private static readonly ConcurrentDictionary<string, ExClient> _clientInstances = new ConcurrentDictionary<string, ExClient>();
private static readonly ConcurrentDictionary<string, object> _clientLocks = new ConcurrentDictionary<string, object>();
private readonly ConcurrentDictionary<string, SocketServer> _serverInstances = new ConcurrentDictionary<string, SocketServer>();
internal IEnumerable<SocketServer> ServerList => _serverInstances.Values;
public IClient GetClient(IPEndPoint endpoint, bool use_cachee, IRouter router = null)
{
if (use_cachee)
{
string key = $"{endpoint.Address}:{endpoint.Port}";
if (false == _clientLocks.ContainsKey(key))
{
_clientLocks.TryAdd(key, new object());
}
lock (_clientLocks[key])
{
try
{
ExClient instance = null;
if (_clientInstances.ContainsKey(key))
{
instance = _clientInstances[key];
if (instance.Status == SocketClientStatus.Working)
{
return instance;
}
_clientInstances.TryRemove(key, out instance);
instance.Dispose();
instance = null;
}
instance = new ExClient(new SocketClient(endpoint, router ?? new Router()));
if (instance.Status == SocketClientStatus.Initialized
|| instance.Status == SocketClientStatus.Working)
{
_clientInstances[key] = instance;
return instance;
}
}
catch (Exception ex)
{
Log.SystemError(ex, $"[ExClientServerCachee.GetClient] Can't create ExClient for {key}");
}
}
}
else
{
var instance = new ExClient(new SocketClient(endpoint, router ?? new Router()));
if (instance.Status == SocketClientStatus.Initialized
|| instance.Status == SocketClientStatus.Working)
{
return instance;
}
}
return null;
}
public SocketServer GetServer(IPEndPoint endpoint, IRouter router)
{
string key = $"{endpoint.Address}:{endpoint.Port}";
if (_serverInstances.ContainsKey(key))
{
return _serverInstances[key];
}
var instance = new SocketServer(endpoint, router);
_serverInstances[key] = instance;
return instance;
}
public void Dispose()
{
ExClient removed;
var clients = new HashSet<string>(_clientInstances.Keys);
foreach (var client in clients)
{
try
{
if (_clientInstances.TryRemove(client, out removed))
{
removed.Dispose();
}
}
catch (Exception ex)
{
Log.Error(ex, $"[ExClientServerCachee.Dispose()] Dispose SocketClient to endpoint {client}");
}
}
foreach (var server in _serverInstances)
{
try
{
server.Value.Dispose();
}
catch (Exception ex)
{
Log.Error(ex, $"[ExClientServerCachee.Dispose()] Dispose SocketServer with endpoint {server.Key}");
}
}
_serverInstances.Clear();
}
}
}

Powered by TurnKey Linux.