using Azylee.Core.ThreadUtils.SleepUtils;
using Azylee.Core.WindowsUtils.ConsoleUtils;
using Azylee.Jsons;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Azylee.YeahWeb.SocketUtils.TcpUtils
{
///
/// Tcp 服务工具
///
public class TcppServer
{
const int ReceiveBufferSize = 1024;
private List ReceiveByte = new List();
private int _Port = 52801;
TcpListener Listener = null;
TcpDelegate.ReceiveMessage ReceiveMessage;
TcpDelegate.OnConnect OnConnect;
TcpDelegate.OnDisconnect OnDisconnect;
List Clients = new List();
///
/// 构造函数
///
/// 端口号
/// 接收消息
/// 连接动作
/// 断开动作
public TcppServer(int port,
TcpDelegate.ReceiveMessage receive,
TcpDelegate.OnConnect connect,
TcpDelegate.OnDisconnect disconnect)
{
_Port = port;
ReceiveMessage += receive;
OnConnect += connect;
OnDisconnect += disconnect;
}
#region 启动和停止服务
///
/// 启动服务
///
public void Start()
{
this.Listener = new TcpListener(IPAddress.Any, _Port);
this.Listener.Start();
this.Listener.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), this.Listener);
}
///
/// 停止服务
///
public void Stop()
{
foreach (var client in Clients)
{
client?.Client?.Close();
}
Clients.Clear();
this.Listener?.Stop();
}
#endregion
#region 连接后的读写操作
///
/// 发送数据
///
/// 主机地址
/// 数据模型
public void Write(string host, TcpDataModel model)
{
var dictionary = Clients_Get(host);
if (dictionary != null && dictionary.Client != null)
{
if (dictionary.Client.Connected)
{
bool flag = TcpStreamHelper.Write(dictionary.Client, model);
}
}
}
///
/// 发送数据
///
/// 主机地址
/// 类型
/// 数据
public void Write(string host, int type, byte[] data)
{
Write(host, new TcpDataModel() { Type = type, Data = data });
}
///
/// 发送数据
///
/// 主机地址
/// 类型
/// 字符串
public void Write(string host, int type, string s)
{
Write(host, new TcpDataModel() { Type = type, Data = Json.Object2Byte(s) });
}
private void acceptCallback(IAsyncResult state)
{
try
{
TcpListener lstn = (TcpListener)state.AsyncState;
TcpClient client = lstn.EndAcceptTcpClient(state);
string host = client.Client.RemoteEndPoint.ToString();
Clients_Add_Update(host, client);
ConnectTask(host, client);
lstn.BeginAcceptTcpClient(new AsyncCallback(acceptCallback), lstn);
}
catch { }
}
private void ConnectTask(string host, TcpClient client)
{
DateTime HeartbeatTime = DateTime.Now;
//发送心跳
Task.Factory.StartNew(() =>
{
while (client.Connected)
{
TcpDataModel model = new TcpDataModel() { Type = int.MaxValue };
TcpStreamHelper.Write(client, model);
Sleep.S(5);
//if (DateTime.Now.AddSeconds(-10) > HeartbeatTime)
// client.Close();
Sleep.S(5);
}
});
//接收消息
Task.Factory.StartNew(() =>
{
OnConnect?.Invoke(host);//委托:已连接
while (client.Connected)
{
try
{
TcpDataModel model = TcpStreamHelper.Read(client);
if (model != null)
{
if (model.Type == int.MaxValue)
{
//过滤心跳
HeartbeatTime = DateTime.Now;
}
else
{
ReceiveMessage(host, model);//委托:接收消息
}
}
}
catch { }
//Sleep.S(1);
}
client.Close();
Clients_Del(host);
OnDisconnect?.Invoke(host);//委托:断开连接
});
}
#endregion
#region 连接的客户端列表维护
///
/// 获取连接的客户端
///
///
private TcpClientDictionary Clients_Get(string host)
{
TcpClientDictionary client = null;
try
{
client = Clients.FirstOrDefault(x => x.Host == host);
}
catch { }
return client;
}
///
/// 添加或更新到客户端列表
///
private void Clients_Add_Update(string host, TcpClient client)
{
try
{
var item = Clients.FirstOrDefault(x => x.Host == host);
if (item == null)
{
Clients.Add(new TcpClientDictionary() { Host = host, Client = client });
}
else
{
item.Client = client;
}
}
catch { }
}
///
/// 从客户端列表中删除
///
private int Clients_Del(string host)
{
int count = 0;
try
{
count = Clients.RemoveAll(x => x.Host == host);
}
catch { }
return count;
}
///
/// 当前连接客户端总数
///
///
public int ClientsCount()
{
return Clients.Count();
}
#endregion
}
}