using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace SKMC.Api.Common.Tcp
{
public class TcpClientBase
{
protected static readonly ILogger log = LogFactory.Get();
public string Address { get; set; } = "127.0.0.1";
public int Port { get; set; }
public int TIMEOUT { get; set; } = 5000;
// 是否长连接
public bool KeepAlived { get; set; } = false;
// 测试模式(空跑模式)下, 不等待接收响应
public bool TestMode { get; set; } = false;
// 是否开启
public bool Enabled { get; set; } = true;
public bool Logged { get; set; } = true;
// 是否运行中, 结束运行可放弃等待服务端响应数据
public bool Running { get; set; }
private TCPClient client;
public TcpClientBase(string address, int port)
{
Address = address;
Port = port;
client = new TCPClient(Address, Port) { KeepAlived = KeepAlived };
}
///
/// 保持连接, 如果连接已中断则重新连接
///
/// 验证连接的超时时间(ms)
///
public TCPClient Connect(int mills)
{
if (!Enabled) return null;
if (!KeepAlived || !client.IsConnected(mills))
{
client.Connect();
}
return client;
}
public TCPClient Connect()
{
if (!Enabled) return null;
if (client != null) client.Connect();
return client;
}
public void Reset(int index)
{
if (client != null) client.Clear();
Running = false;
}
///
/// 请求并获取结果
/// 请求后阻塞获取确认消息
/// 再异步接收结果
///
/// 请求消息
/// 响应结果解析
///
public Task RequestAndResult(string requestMsg, bool sync = false, Action responseAction = null, Action resultAction = null)
{
string response = null;
string result = null;
try
{
client = Connect(100);
Reset(0);
client.Send(requestMsg, Logged);
response = client.Recevie(Logged);
if (sync)
{
resultAction?.Invoke(response);
if (!KeepAlived) client.Close();
}
else
{
// 异步模式, 视觉采图响应
try
{
responseAction?.Invoke(response);
}
catch (Exception e)
{
throw new Exception($"Response Parse(Aync) Error", e);
}
}
if (sync) return null;
return Task.Run(() =>
{
try
{
result = client.Recevie(Logged);
resultAction?.Invoke(result);
if (!KeepAlived) client.Close();
}
catch (Exception e)
{
throw new Exception($"Result Parse(Aync) Error", e);
}
});
}
catch (SocketException ex)
{
switch ((SocketError)ex.ErrorCode)
{
case SocketError.TimedOut:
throw new Exception($"接收超时: [{Address} : {Port}]", ex);
case SocketError.ConnectionRefused:
throw new Exception($"连接被拒绝: [{Address} : {Port}]", ex);
case SocketError.HostNotFound:
throw new Exception($"地址未找到: [{Address} : {Port}]", ex);
case SocketError.NetworkDown:
throw new Exception($"网络不可用: [{Address} : {Port}]", ex);
case SocketError.AddressAlreadyInUse:
throw new Exception($"地址已被使用: [{Address} : {Port}]", ex);
default:
throw new Exception($"其他Socket异常: [{Address} : {Port}]", ex);
}
}
catch (Exception e)
{
throw e;
}
}
}
}