using Microsoft.Extensions.Logging; using SlnMesnac.Config; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TouchSocket.Core; using TouchSocket.Sockets; namespace SlnMesnac.TouchSocket { public class TcpServer { private DebugConfig config = DebugConfig.Instance; private ILogger _logger; private readonly TcpService _service; #region 委托事件 /// /// 刷新扫码器状态 /// /// /// public delegate void RefreshState(string ip, bool flag); public static event RefreshState RefreshStateEvent; //NoRead事件通知 //public delegate void MessageNoRead(); //public static event MessageNoRead MessageNoReadEvent; //扫码事件 public delegate void RefreshMaterialCodeStr(string materialCodeStr, string ip); public static event RefreshMaterialCodeStr RefreshMaterialCodeStrEvent; //相机拍照识别结果 public delegate void CameraResult(string result); public static event CameraResult CameraResultEvent; //光电信号推送 public delegate void SerialSignalPush(string ip, int flag); public static event SerialSignalPush SerialSignalPushEvent; #endregion public TcpServer(ILogger logger,TcpService tcpService) { _logger = logger; _service = tcpService; } public void Init(int serverPort) { try { Console.WriteLine("启动Socket服务"); _service.Connecting = (client, e) => { _logger.LogInformation($"客户端{client.IP}正在接入服务"); return EasyTask.CompletedTask; }; _service.Connected = (client, e) => { _logger.LogInformation($"客户端{client.IP}接入服务成功"); RefreshStateEvent?.Invoke(client.IP, true); return EasyTask.CompletedTask; }; _service.Disconnected = (client, e) => { _logger.LogInformation($"客户端{client.IP}断开连接"); RefreshStateEvent?.Invoke(client.IP, false); return EasyTask.CompletedTask; }; _service.Received = (client, e) => { try { // 串口模块光电信号 if (client.IP == config.SerialIP) { int result = ChangeSerialSignal(e.ByteBlock.Buffer,e.ByteBlock.Len); if(result == -1) { client.Logger.Info($"{client.IP}:{client.Port}》接收到光电信息异常"); } else { string message = result == 1 ? "触发" : "释放"; client.Logger.Info($"{client.IP}:{client.Port}》接收到光电信息:{message}"); SerialSignalPushEvent?.Invoke(client.IP, result); } } else //扫码器及相机 { //从客户端收到信息 var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意:数据长度是byteBlock.Len //心跳包 if (mes == "heartbeat") { //扫码器心跳连接 client.Logger.Info($"心跳{client.IP}:{client.Port}》接收到心跳信息:{mes}"); RefreshStateEvent?.Invoke(client.IP, true); } else if (mes == "NoRead") { client.Logger.Info($"客户端{client.IP}:{client.Port}》NoRead事件{mes}"); // TODO扫码器扫码失败报警 } else { string code = mes.Trim().TrimEnd('\0'); client.Logger.Info($"客户端{client.IP}:{client.Port}》接收到信息:{mes}"); // 区分相机扫码器数据 if (client.IP == config.ScannerIP) { if (code.Contains("heart")) { return Task.CompletedTask; } RefreshMaterialCodeStrEvent?.Invoke(code, client.IP); } else if (client.IP == config.CameraIP) { // 相机返回数据 CameraResultEvent?.Invoke(code); } } } } catch (Exception ex) { _logger.LogError($"socket接收数据异常:{ex.Message}"); } return EasyTask.CompletedTask; }; _service.Setup(new TouchSocketConfig()//载入配置 .SetListenIPHosts(new IPHost[] { new IPHost($"0.0.0.0:{serverPort}") }) .ConfigureContainer(a =>//容器的配置顺序应该在最前面 { a.AddConsoleLogger(); }) .ConfigurePlugins(a => { //自定义插件 })); _service.Start(); _logger.LogInformation($"TcpServer启动成功,监听端口:{serverPort}"); } catch (Exception ex) { //throw new InvalidOperationException($"TcpServer启动异常:{ex.Message}"); _logger.LogError($"TcpServer启动异常:{ex.Message}"); } } /// /// 向所有客户端发送心跳 /// //public void SendHeartBeat() //{ // var clients = _service.SocketClients.GetClients(); // foreach (var item in clients) // { // _service.Send(item.Id, "heartbeat"); // } //} /// /// 向指定相机发送指令 /// public void SendCommand(string ip, string command) { ISocketClient client = _service.SocketClients.GetClients().FirstOrDefault(x => x.IP ==ip); if (client != null) { _service.Send(client.Id, command); } } /// /// 转换光电信号 /// 释放 01 03 02 01 00 B9 D4 /// 触发 01 03 02 01 FF F9 94 /// /// public int ChangeSerialSignal(byte[] data,int len) { try { if (data == null || len < 0) { return -1; } len = Math.Min(len, data.Length); byte[] CheckByte = new byte[len]; Array.Copy(data, 0, CheckByte, 0, len); byte[] release = new byte[] { (byte)0x01, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0x00, (byte)0xB9, (byte)0xD4 }; byte[] trigger = new byte[] { (byte)0x01, (byte)0x03, (byte)0x02, (byte)0x01, (byte)0xFF, (byte)0xF9, (byte)0x94 }; if (CheckByte.Length == release.Length && CheckByte.SequenceEqual(release)) { return 0; } else if (CheckByte.Length == trigger.Length && CheckByte.SequenceEqual(trigger)) { return 1; } // 异常 return -1; }catch(Exception ex) { return -1; } } } }