LaserRemoval.cs 10.7 KB
using HHECS.BllModel;
using HHECS.Infrastructure.Enums;
using HHECS.Infrastructure.Notice;
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading;

namespace HHECS.Executor.EquipmentHandler.Marking
{
    /// <summary>
    /// 
    /// 激光除锈信号发送
    /// </summary>
    public class LaserRemoval
    {
        private static Dictionary<string, ServerConnection> servers = new Dictionary<string, ServerConnection>();
        private static readonly object serversLock = new object();
        private static bool isRunning = true;
      public  static BllResult ConnectToServer(string serverId, string host, int port)
        {
            // 检查是否已连接到该服务器
            lock (serversLock)
            {
                if (servers.ContainsKey(serverId))
                {
                    return BllResultFactory.Success($"已连接到服务器 {serverId}");
                }
            }
          
            // 创建新的服务器连接
            ServerConnection connection = new ServerConnection
            {
                ServerId = serverId,
                Host = host,
                Port = port,
                LastHeartbeat = DateTime.Now
            };

            // 启动连接线程
            Thread connectThread = new Thread(() => Connect(connection));
            connectThread.IsBackground = true;
            connectThread.Start();
            return BllResultFactory.Success();
        }

        static void Connect(ServerConnection connection)
        {
            try
            {
                TcpClient client = new TcpClient();
                client.Connect(connection.Host, connection.Port);

                // 连接成功,更新连接信息
                lock (serversLock)
                {
                    connection.Client = client;
                    connection.Connected = true;
                    servers[connection.ServerId] = connection;
                }
                NoticeBus.Notice($"成功连接到服务器 {connection.ServerId}", Level.Info);
                // 发送设备标识
                //SendMessage(connection, new Message
                //{
                //    Type = "IDENTIFY",
                //    DeviceId = "ClientDevice",
                //    Content = "Client Connected"
                //});

                // 启动接收线程
                Thread receiveThread = new Thread(() => ReceiveMessages(connection));
                receiveThread.IsBackground = true;
                receiveThread.Start();

                // 启动心跳线程
                Thread heartbeatThread = new Thread(() => SendHeartbeats(connection));
                heartbeatThread.IsBackground = true;
                heartbeatThread.Start();
            }
            catch (Exception ex)
            {
                NoticeBus.Notice($"连接服务器 {connection.ServerId} 失败: {ex.Message}", Level.Error);

                // 连接失败,尝试重连
                Reconnect(connection);
            }
        }

       public static void Reconnect(ServerConnection connection)
        {
            // 标记为未连接
            lock (serversLock)
            {
                connection.Connected = false;
                if (connection.Client != null)
                {
                    try { connection.Client.Close(); } catch { }
                    connection.Client = null;
                }
            }
            Thread.Sleep(5000);

            // 重新连接
            if (isRunning)
            {
                Thread connectThread = new Thread(() => Connect(connection));
                connectThread.IsBackground = true;
                connectThread.Start();
            }
        }

        static void ReceiveMessages(ServerConnection connection)
        {
            NetworkStream stream = null;
            byte[] buffer = new byte[1024];

            try
            {
                while (isRunning && connection.Connected && connection.Client.Connected)
                {
                    if (stream == null)
                        stream = connection.Client.GetStream();

                    if (!IsConnected(connection.Client))
                        break;

                    // 检查是否有数据可读
                    if (connection.Client.Available > 0)
                    {
                        int bytesRead = stream.Read(buffer, 0, buffer.Length);
                        if (bytesRead > 0)
                        {
                            string data = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                            Message message = Message.Parse(data);
                            message.DeviceId = connection.ServerId;
                            message.Type = "COMMAND";
                            // 更新心跳时间
                            connection.LastHeartbeat = DateTime.Now;

                            // 处理不同类型的消息
                            switch (message.Type)
                            {
                                case "HEARTBEAT":
                                    NoticeBus.Notice($"收到来自服务器 {connection.ServerId} 的心跳", Level.Error);
                                    break;
                                case "COMMAND":
                                    NoticeBus.Notice($"收到来自服务器 {connection.ServerId} 的命令: {message.Content}", Level.Info);
                                    // 处理命令...
                                    break;
                                default:
                                    NoticeBus.Notice($"收到来自服务器 {connection.ServerId} 的未知类型消息: {message.Type}", Level.Error);
                                    break;
                            }
                        }
                    }
                    else
                    {
                        Thread.Sleep(100);
                    }
                }
            }
            catch (Exception ex)
            {
                NoticeBus.Notice($"从服务器 {connection.ServerId} 接收消息时出错: {ex.Message}", Level.Error);
            }
            finally
            {
                // 连接断开,尝试重连
                if (isRunning)
                {
                    Reconnect(connection);
                }
            }
        }

        static void SendHeartbeats(ServerConnection connection)
        {
            while (isRunning && connection.Connected)
            {
                try
                {
                    //if (connection.Client != null && connection.Client.Connected)
                    //{
                    //    SendMessage(connection, new Message
                    //    {
                    //        Type = "HEARTBEAT",
                    //        DeviceId = "ClientDevice",
                    //        Content = "Ping"
                    //    });
                    //}
                    //else
                    //{
                    //    break;
                    //}
                }
                catch (Exception ex)
                {
                    NoticeBus.Notice($"向服务器 {connection.ServerId} 发送心跳时出错: {ex.Message}", Level.Error);
                    break;
                }

                // 每5秒发送一次心跳
                Thread.Sleep(5000);
            }
        }
       public static BllResult SendMessage(ServerConnection connection, Message message)
        {

            if (!connection.Connected || connection.Client == null || !connection.Client.Connected)
            {

                return BllResultFactory.Error(($"无法发送消息到服务器 {connection.ServerId}: 未连接"));
            }
            try
            {
                string json = message.ToJson();
                byte[] data = Encoding.UTF8.GetBytes(json);
                NetworkStream stream = connection.Client.GetStream();
                stream.Write(data, 0, data.Length);
                return BllResultFactory.Success();
            }
            catch (Exception ex)
            {
             
                Reconnect(connection);
                return BllResultFactory.Error($"向服务器 {connection.ServerId} 发送消息时出错: {ex.Message}");
            }
        }

        // 检查Socket连接是否仍然有效
      public static bool IsConnected(TcpClient client)
        {
            if (client == null || !client.Connected)
                return false;

            Socket socket = client.Client;
            return !(socket.Poll(1000, SelectMode.SelectRead) && socket.Available == 0);
        }
    }

    // 服务器连接信息类
   public class ServerConnection
    {
        public string ServerId { get; set; }
        public string Host { get; set; }
        public int Port { get; set; }
        public TcpClient Client { get; set; }
        public bool Connected { get; set; }
        public DateTime LastHeartbeat { get; set; }
    }

    // 消息类
   public class Message
    {
        public string Type { get; set; }
        public string DeviceId { get; set; }
        public string Content { get; set; }

        public string ToJson()
        {
            return $"{{\"type\":\"{Type}\",\"deviceId\":\"{DeviceId}\",\"content\":\"{Content}\"}}";
        }

        public static Message Parse(string json)
        {
            try
            {
                // 简单解析,实际应用中应使用JSON库
                Message message = new Message();

                // 提取type字段
                int typeStart = json.IndexOf("\"type\":\"") + 8;
                int typeEnd = json.IndexOf("\"", typeStart);
                if (typeStart > 7 && typeEnd > typeStart)
                    message.Type = json.Substring(typeStart, typeEnd - typeStart);

                // 提取deviceId字段
                int deviceIdStart = json.IndexOf("\"deviceId\":\"") + 11;
                int deviceIdEnd = json.IndexOf("\"", deviceIdStart);
                if (deviceIdStart > 10 && deviceIdEnd > deviceIdStart)
                    message.DeviceId = json.Substring(deviceIdStart, deviceIdEnd - deviceIdStart);

                // 提取content字段
                int contentStart = json.IndexOf("\"content\":\"") + 11;
                int contentEnd = json.LastIndexOf("\"");
                if (contentStart > 10 && contentEnd > contentStart)
                    message.Content = json.Substring(contentStart, contentEnd - contentStart);

                return message;
            }
            catch
            {
                return new Message { Type = "UNKNOWN", DeviceId = "UNKNOWN", Content = json };
            }
        }
    }
}