KukaService.cs 7.41 KB
using HHECS.BllModel;
using HHECS.RobotTool.Common;
using HHECS.RobotTool.Dto;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Xml.Serialization;

namespace HHECS.RobotTool.Service
{
    public class KukaService
    {
        private readonly TcpListener _tcpServer;
        private readonly SystemLog _logger = SystemLog.GetInstance();
        private readonly GrooveService _grooveService;

        public KukaService(GrooveService grooveService)
        {
            _tcpServer = new TcpListener(IPAddress.Any, 59152);
            _grooveService = grooveService;
        }

        public BllResult StartTcpServer()
        {
            try
            {
                _tcpServer.Start();
                _tcpServer.BeginAcceptTcpClient(DoAcceptTcpClient, _tcpServer);
                return BllResultFactory.Success();
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error(ex.Message);
            }
        }

        private void DoAcceptTcpClient(IAsyncResult ar)
        {
            try
            {
                var server = (TcpListener)ar.AsyncState!;
                var tcpClient = server.EndAcceptTcpClient(ar);
                _logger.LogInfo($"[客户端[{tcpClient.Client.RemoteEndPoint}]已成功建立连接");
                Receive(tcpClient);
                server.BeginAcceptTcpClient(DoAcceptTcpClient, server);
            }
            catch (Exception ex)
            {
                _logger.LogError($"[TcpServer]异常:{ex.Message}");
            }
        }

        private void Receive(TcpClient tcpClient)
        {
            Task.Run(() =>
            {
                var remoteEndPoint = tcpClient.Client.RemoteEndPoint;
                while (tcpClient.Connected)
                {
                    try
                    {
                        var buffer = new byte[8192];
                        var stream = tcpClient.GetStream();
                        //接收客户端数据
                        stream.Read(buffer, 0, buffer.Length);
                        var bufferString = Encoding.Default.GetString(buffer).TrimEnd('\0');

                        if (string.IsNullOrWhiteSpace(bufferString)) continue;

                        _logger.LogInfo($"接收到客户端[{remoteEndPoint}]报文:{bufferString}");

                        const string kukaAckFlag1 = "<Robot>";
                        const string kukaAckFlag2 = "</Robot>";
                        if (bufferString.StartsWith(kukaAckFlag1, StringComparison.OrdinalIgnoreCase)
                        && bufferString.EndsWith(kukaAckFlag2, StringComparison.OrdinalIgnoreCase))
                        {
                            var kukaHandleResult = KukaTcpHandle(bufferString, stream, remoteEndPoint);
                            if (kukaHandleResult.Success)
                            {
                                _logger.LogSuccess($"响应客户端[{remoteEndPoint}]请求成功");
                            }
                            else
                            {
                                _logger.LogError($"响应客户端[{remoteEndPoint}]请求失败:{kukaHandleResult.Msg}");
                            }
                        }
                        else
                        {
                            _logger.LogInfo($"收到客户端[{remoteEndPoint}]报文:{bufferString}");
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"客户端[{remoteEndPoint}]:{ex.InnerException?.Message ?? ex.Message}");
                    }
                }
            });
        }

        /// <summary>
        /// Kuka Tcp交互处理
        /// </summary>
        /// <param name="bufferString"></param>
        /// <param name="stream"></param>
        private BllResult KukaTcpHandle(string bufferString, NetworkStream stream, EndPoint? remoteEndPoint)
        {
            var inputXmlSerializer = new XmlSerializer(typeof(KukaRequestDto));
            var outputXmlSerializer = new XmlSerializer(typeof(KukaResponseDto));
            using var ms = new MemoryStream();
            var writer = new StreamWriter(ms);
            writer.Write(bufferString.Trim());
            writer.Flush();
            ms.Position = 0;
            var reader = new StreamReader(ms);
            try
            {
                var request = (KukaRequestDto)inputXmlSerializer.Deserialize(reader)!;
                var inputResult = _grooveService.GetInputParameterDefault(request.Code);
                if (!inputResult.Success)
                {
                    return BllResultFactory.Error($"获取默认输入参数失败:{inputResult.Msg}");
                }

                //默认值
                var inputParameter = inputResult.Data;
                inputParameter.GrooveWidth = request.GrooveWidth;
                inputParameter.GrooveDepth = request.GrooveDepth;

                var result = _grooveService.GetComputedData(inputParameter);
                if (!result.Success)
                {
                    return BllResultFactory.Error($"数据计算出现异常:{result.Msg}");
                }
                var (outputParameter, _) = result.Data;

                var resultData = new KukaResponseDto
                {
                    Weld_Num = outputParameter.Weld_Num,
                    WeldHeightAfterWelding = outputParameter.WeldHeightAfterWelding,
                    WeldWidthAfterWelding = outputParameter.WeldWidthAfterWelding,
                    GrooveCrossSectionalArea = outputParameter.GrooveCrossSectionalArea,
                    OneLayerWireFeedingSpeed = outputParameter.OneLayerWireFeedingSpeed,
                    OneLayerCurrent = outputParameter.OneLayerCurrent,

                    CoverWireFeedingSpeed = outputParameter.CoverWireFeedingSpeed,
                    CoverWireFeedingCurrent = outputParameter.CoverWireFeedingCurrent,
                    WeldingWireCrossSectionalArea = outputParameter.WeldingWireCrossSectionalArea,
                    Layers = outputParameter.Layers,
                    TotalDepositionAmount = outputParameter.TotalDepositionAmount,
                    WeldingWireLengthAndUsage = outputParameter.WeldingWireLengthAndUsage,
                    TotalDepositionTime = outputParameter.TotalDepositionTime,

                    WeldingWire = inputParameter.WeldingWire,
                    ReservedGapForGroove = inputParameter.ReservedGap,
                    SizeOfTheBluntEdgeOfTheGroove = inputParameter.BluntEdgeSize,
                    WeldLength = inputParameter.WeldLength,
                    AdditionalWidthRequiredOnOneSideAfterCovering = inputParameter.WeldWidth,
                    WeldReinforcementRequiredAfterCovering = inputParameter.WeldHeight
                };

                using var sw = new StringWriter();
                outputXmlSerializer.Serialize(sw, resultData);
                var response = sw.ToString();
                stream.Write(Encoding.Default.GetBytes(response));
                _logger.LogInfo($"响应客户端[{remoteEndPoint}]请求报文:{response}");
                return BllResultFactory.Success();
            }
            catch (Exception ex)
            {
                return BllResultFactory.Error(ex.Message);
            }
        }

        public void StopTcpServer()
        {
            _tcpServer.Stop();
        }
    }
}