//------------------------------------------------------------------------------
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
// CSDN博客:https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频:https://space.bilibili.com/94253567
// Gitee源代码仓库:https://gitee.com/RRQM_Home
// Github源代码仓库:https://github.com/RRQM
// API首页:https://www.yuque.com/rrqm/touchsocket/index
// 交流QQ群:234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Threading;
using TouchSocket.Core;
namespace TouchSocket.Sockets
{
///
/// 适用于Tcp客户端的连接工厂。
///
///
public class TcpClientFactory : ClientFactory where TClient : ITcpClient, new()
{
private readonly TClient m_mainClient = new TClient();
private readonly SingleTimer m_singleTimer;
private bool first = true;
///
/// 适用于Tcp客户端的连接工厂。
///
public TcpClientFactory()
{
m_singleTimer = new SingleTimer(1000, () =>
{
List list = new List();
foreach (var item in this.CreatedClients)
{
if (!this.IsAlive(item))
{
list.Add(item);
}
}
foreach (var item in list)
{
this.DisposeClient(item);
}
if (IsAlive(this.MainClient))
{
if (this.CreatedClients.Count < this.MinCount)
{
try
{
this.CreateTransferClient();
}
catch
{
}
}
}
});
}
///
/// 连接超时设定
///
public TimeSpan ConnectTimeout { get; set; } = TimeSpan.FromSeconds(5);
///
public override TClient MainClient { get => m_mainClient; }
///
/// 获取传输的客户端配置
///
public Func OnGetTransferConfig { get; set; }
///
public override Result CheckStatus(bool tryInit = true)
{
lock (this.m_singleTimer)
{
try
{
if (!IsAlive(m_mainClient))
{
if (!tryInit)
{
return Result.UnknownFail;
}
if (first)
{
OnMainClientSetuping();
MainClient.Setup(this.MainConfig);
first = false;
}
MainClient.Close();
MainClient.Connect((int)this.ConnectTimeout.TotalMilliseconds);
}
return Result.Success;
}
catch (Exception ex)
{
return new Result(ex);
}
}
}
///
/// 在主客户端加载配置之前
///
protected virtual void OnMainClientSetuping()
{
}
///
public override void DisposeClient(TClient client)
{
client.TryShutdown();
client.SafeDispose();
this.CreatedClients.Remove(client);
}
///
/// 获取可以使用的客户端数量。
///
/// 注意:该值不一定是的长度,当已创建数量小于设定的最大值时,也会累加未创建的值。
///
///
///
public override int GetAvailableCount()
{
return Math.Max(0, this.MaxCount - this.CreatedClients.Count) + this.FreeClients.Count;
}
///
/// 获取一个空闲的连接对象,如果等待超出设定的时间,则会创建新的连接。
///
/// 指定毫秒数
///
///
///
public TClient GetTransferClient(int waitTime)
{
return this.GetTransferClient(TimeSpan.FromMilliseconds(waitTime));
}
///
/// 获取一个空闲的连接对象,如果等待超出1秒的时间,则会创建新的连接。
///
///
///
///
public TClient GetTransferClient()
{
return this.GetTransferClient(TimeSpan.FromSeconds(1));
}
///
/// 获取一个空闲的连接对象,如果等待超出设定的时间,则会创建新的连接。
///
///
///
///
///
public override TClient GetTransferClient(TimeSpan waitTime)
{
while (FreeClients.TryDequeue(out var client))
{
if (IsAlive(client))
{
return client;
}
else
{
DisposeClient(client);
}
}
if (this.CreatedClients.Count > MaxCount)
{
if (SpinWait.SpinUntil(Wait, waitTime))
{
return GetTransferClient(waitTime);
}
}
var clientRes = CreateTransferClient();
return clientRes;
}
///
public override bool IsAlive(TClient client)
{
return client.Online;
}
///
/// 归还使用完的连接。
///
/// 首先内部会判定存活状态,如果不再活动状态,会直接调用。
/// 其次会计算是否可以进入缓存队列,如果队列数量超出,也会直接调用
///
///
///
public override void ReleaseTransferClient(TClient client)
{
if ((object)client == (object)MainClient)
{
return;
}
if (!IsAlive(client))
{
DisposeClient(client);
return;
}
if (FreeClients.Count < MaxCount)
{
FreeClients.Enqueue(client);
}
else
{
DisposeClient(client);
}
}
///
///
///
///
protected override void Dispose(bool disposing)
{
this.m_singleTimer.SafeDispose();
base.Dispose(disposing);
}
///
protected override TouchSocketConfig GetTransferConfig()
{
return OnGetTransferConfig?.Invoke();
}
private TClient CreateTransferClient()
{
TClient client = new TClient();
client.Setup(this.GetTransferConfig());
client.Connect((int)ConnectTimeout.TotalMilliseconds);
this.CreatedClients.Add(client);
return client;
}
private bool Wait()
{
if (FreeClients.Count > 0)
{
return true;
}
return false;
}
}
///
/// 适用于基于的连接工厂。
///
public class TcpClientFactory : TcpClientFactory
{
}
}