You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
6.7 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using HighWayIot.Common;
using HighWayIot.Log4net;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using TouchSocket.Core;
using TouchSocket.Sockets;
namespace HighWayIot.TouchSocket
{
/// <summary>
/// 消息接收
/// </summary>
public class TcpServer
{
private static readonly Lazy<TcpServer> lazy = new Lazy<TcpServer>(() => new TcpServer());
public static TcpServer Instance => lazy.Value;
private MsgUtil msgUtil = MsgUtil.Instance;
private static LogHelper logHelper = LogHelper.Instance;
private ServerBufferAnalysis _serverBufferAnalysis = ServerBufferAnalysis.Instance;
private MessageFactory _messageFactory = MessageFactory.Instance;
private XmlUtil _xmlUtil = XmlUtil.Instance;
private List<ClientsConfig> clientsConfigs;
public ServerState State
{
get => service.ServerState;
private set => State = value;
}
public bool ServerState
{
get => !(service == null);
}
private TcpService service = new TcpService();
public List<string> Ids
{
get => service.Clients.Select(x => x.Id).ToList();
}
public int ConnectCount
{
get => service.Clients.Count;
}
public TcpServer()
{
clientsConfigs = _xmlUtil.ClientReader();
_messageFactory.MessegeSend += SendMessage;
}
public bool ServerStart(string host)
{
service = new TcpService();
try
{
service.Connecting = (client, e) =>
{
logHelper.Info($"客户端{client.IP}:{client.Port}正在连接");
return EasyTask.CompletedTask;
};//有客户端正在连接
service.Connected = (client, e) =>
{
logHelper.Info($"客户端{client.IP}:{client.Port}成功连接");
var now = clientsConfigs.Where(x => x.IP == client.IP && x.Port == client.Port.ToString()).FirstOrDefault();
if (now == null)
{
//如果配置文件端口为0就都能连
if(clientsConfigs.Where(x => x.IP == client.IP).FirstOrDefault().Port == "0")
{
Ids.Add(client.Id);
return EasyTask.CompletedTask;
}
client.Close();
}
else
{
client.ResetIdAsync(now.ID);
Ids.Add(now.ID);
}
return EasyTask.CompletedTask;
};//有客户端成功连接
service.Closing = (client, e) =>
{
logHelper.Info($"客户端{client.IP}:{client.Port}正在断开连接");
return EasyTask.CompletedTask;
};//有客户端正在断开连接,只有当主动断开时才有效。
service.Closed = (client, e) =>
{
logHelper.Info($"客户端{client.IP}:{client.Port}断开连接");
Ids.Remove(client.Id);
return EasyTask.CompletedTask;
};//有客户端断开连接
service.Received = (client, e) =>
{
var mes = e.ByteBlock.Span.ToArray();
Console.WriteLine(">>>>>" + msgUtil.bytesToHexStr(mes, mes.Length));
_messageFactory.Factory(_serverBufferAnalysis.BaseUnpackServerBufferAnalysis(mes), client.Id);
return EasyTask.CompletedTask;
};
service.Setup(new TouchSocketConfig()//载入配置
.SetListenOptions(option =>
{
option.Add(new TcpListenOption()
{
IpHost = host,
Name = "Server",//名称用于区分监听
ServiceSslOption = null,//可以针对当前监听单独启用ssl加密
Adapter = () => new NormalDataHandlingAdapter(),//可以单独对当前地址监听,配置适配器
//还有其他可配置项,都是单独对当前地址有效。
});
})
.ConfigureContainer(a =>//容器的配置顺序应该在最前面
{
a.AddConsoleLogger();//添加一个控制台日志注入注意在maui中控制台日志不可用
})
.ConfigurePlugins(a =>
{
//a.Add();//此处可以添加插件
}));
service.Start();//启动
logHelper.Info("监听服务启动成功");
return true;
}
catch (Exception ex)
{
logHelper.Error("监听服务启动失败! 错误代码" + ex.ToString());
return false;
}
}
/// <summary>
/// 信息发送
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
public void SendMessage(byte[] message, string id)
{
try
{
service.SendAsync(id, message).GetAwaiter().GetResult();
Console.WriteLine("<<<<<" + msgUtil.bytesToHexStr(message, message.Length));
}
catch (Exception ex)
{
logHelper.Error("发送信息失败! 错误代码" + ex.ToString());
}
}
public bool ServerStop()
{
try
{
service.Stop();
logHelper.Info("监听服务关闭成功!");
return true;
}
catch (Exception ex)
{
logHelper.Error("监听服务关闭失败! 错误代码" + ex.ToString());
return false;
}
}
public bool ServerDispose()
{
try
{
service.Dispose();
logHelper.Info("监听服务释放成功!");
return true;
}
catch (Exception ex)
{
logHelper.Error("监听服务释放失败! 错误代码" + ex.ToString());
return false;
}
}
}
}