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.

232 lines
8.6 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 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<TcpServer> _logger;
private readonly TcpService _service;
#region 委托事件
/// <summary>
/// 刷新扫码器状态
/// </summary>
/// <param name="materialCodeStr"></param>
/// <param name="ip"></param>
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<TcpServer> 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}");
}
}
/// <summary>
/// 向所有客户端发送心跳
/// </summary>
//public void SendHeartBeat()
//{
// var clients = _service.SocketClients.GetClients();
// foreach (var item in clients)
// {
// _service.Send(item.Id, "heartbeat");
// }
//}
/// <summary>
/// 向指定相机发送指令
/// </summary>
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);
}
}
/// <summary>
/// 转换光电信号
/// 释放 01 03 02 01 00 B9 D4
/// 触发 01 03 02 01 FF F9 94
/// </summary>
/// <returns></returns>
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;
}
}
}
}