Files
46-Pingzhi126-ZZ-WebApi/Tighten/TightenServer.cs
2026-06-08 17:19:25 +08:00

257 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Logger;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.Remoting.Contexts;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using WebApi.Helpers;
using WebApi.Models;
namespace WebApi.Tighten
{
public class TightenServer
{
Dictionary<string,string> SendCode = new Dictionary<string,string>
{
{ "connect", "0020 0001 0050 0001 0000" }, // 建立通讯
{ "heart", "00209999001000010000" }, // 心跳
{ "curve", "00200900000000000000" }, // 曲线
{ "result", "00200060001000010000" }, // 订阅结果
{ "tightenOk", "00200062001000000000" } // 确认收到结果
};
public static event Action<string> ShowMsg; // 记录日志事件
private bool _heartbeatRunning = false;
public void InitTightenList()
{
RedTightenList();
//Connect();
StartHeartbeatLoop();
StartReadData();
}
public void Connect()
{
try
{
foreach (KeyValuePair<string, TightenTool> kvp in Gl.TightenList)
{
if (!kvp.Value.IsConnected)
{
kvp.Value.TcpClient.Connect(kvp.Value.IP, Convert.ToInt32(kvp.Value.Port));
if (kvp.Value.IsConnected)
{
string ErrMsg;
// 创建工具连接
if (!TightenHelpers.Send(kvp.Value.TcpClient, SendCode["connect"], out ErrMsg))
{
Log.Error(kvp.Value.IP + "" + ErrMsg);
return;
}
// 心跳
if (!TightenHelpers.Send(kvp.Value.TcpClient, SendCode["heart"], out ErrMsg))
{
Log.Error(kvp.Value.IP + "" + ErrMsg);
return;
}
// 订阅结果
if (!TightenHelpers.Send(kvp.Value.TcpClient, SendCode["result"], out ErrMsg))
{
Log.Error(kvp.Value.IP + "" + ErrMsg);
return;
}
}
}
}
}
catch (Exception ex) {
Log.FunError(ex, MethodBase.GetCurrentMethod().Name);
}
}
private void RedTightenList()
{
SqlServer.ExecuteSql("SELECT * FROM PTCHV_基础表_拧紧枪", out DataTable dt, out string err);
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows) {
var tool = new TightenTool();
tool.OpName = dr["OpName"].ToString();
tool.Name = dr["Name"].ToString();
tool.IP = dr["IP"].ToString();
tool.Port = dr["Port"].ToString();
tool.TcpClient = new System.Net.Sockets.TcpClient();
Gl.TightenList.TryAdd(tool.IP, tool);
}
}
}
private bool SaveTightenData(string opName,string toolName,string max,string min,string OkValue,string value)
{
bool isOk = false;
var param = new Dictionary<string, Object>{
{ "工位号", opName },
{ "拧紧枪名称", toolName },
{ "上限值", max },
{ "下限值", min },
{ "标准值", OkValue },
{ "值", value }
};
SqlServer.ExecuteProcedure("PTCHV_质量数据_增加", param, out DataTable dt, out string err);
if (dt.Rows.Count > 0)
{
if(dt.Rows[0]["result"].ToString() == "1")
{
isOk = true;
}
}
return isOk;
}
// 开启心跳轮询 同时监听数据
public void StartHeartbeatLoop()
{
foreach (var kvp in Gl.TightenList)
{
var tool = kvp.Value;
Task.Run(async () =>
{
while (true)
{
try
{
if (tool.TcpClient == null)
tool.TcpClient = new TcpClient();
if (!tool.IsConnected)
{
try
{
tool.TcpClient.Close();
}
catch { }
tool.TcpClient = new TcpClient();
// 连接加超时
var connectTask = tool.TcpClient.ConnectAsync(tool.IP, Convert.ToInt32(tool.Port));
if (await Task.WhenAny(connectTask, Task.Delay(3000)) == connectTask)
{
// 连接成功
string errMsg;
TightenHelpers.Send(tool.TcpClient, SendCode["connect"], out errMsg);
TightenHelpers.Send(tool.TcpClient, SendCode["heart"], out errMsg);
TightenHelpers.Send(tool.TcpClient, SendCode["result"], out errMsg);
if(errMsg == "")
{
Log.Info($"拧紧枪【{tool.Name}】 连接成功!");
}
}
else
{
//Log.Error($"{tool.IP} 连接超时");
}
}
else
{
string errMsg;
TightenHelpers.Send(tool.TcpClient, SendCode["heart"], out errMsg);
}
}
catch (Exception ex)
{
Log.FunError(ex, "HeartbeatLoop");
}
await Task.Delay(10000);
}
});
}
}
public void StartReadData()
{
foreach (var kvp in Gl.TightenList)
{
Task.Run(async () =>
{
while (true)
{
var tool = kvp.Value;
string ErrMsg = "";
try
{
var client = tool.TcpClient;
bool isConnected = false;
try
{
isConnected = client?.Client?.Connected ?? false;
}
catch (ObjectDisposedException)
{
isConnected = false;
}
catch (Exception ex)
{
Log.Error($"检查连接状态时发生意外错误 for {tool.IP}: {ex.Message}");
isConnected = false;
}
if (isConnected)
{
string command = "";
try
{
if(client != null)
command = TightenHelpers.Read(client, out ErrMsg);
else
continue;
if(ErrMsg != "")
{
Log.Error("【ReadErr】"+kvp.Value.IP + "" + ErrMsg);
}
if (command.Length == 232)
{
TightenHelpers.ParseTorqueData(command, out double min, out double max, out double target, out double actual);
ShowMsg?.Invoke($"【{tool.OpName}{tool.Name} 拧紧数据】最小扭矩: {min}, 最大扭矩: {max}, 目标扭矩: {target}, 实际扭矩: {actual}");
SaveTightenData(tool.OpName, tool.Name, max.ToString(), min.ToString(), target.ToString(), actual.ToString());
await MqttServer.SendMqttMessageToOp(tool.OpName, "TightenOk", "1");
// 发送确认前再次检查连接状态
bool canSend = false;
try
{
canSend = client?.Client?.Connected ?? false;
} catch { /* ignore */ }
if (canSend)
{
TightenHelpers.Send(client, SendCode["tightenOk"], out ErrMsg);
}
}
}
catch (Exception readSendEx) // 捕获读取或发送过程中的异常
{
Log.Error($"读取或发送数据时出错 for {tool.IP}: {readSendEx.Message}");
try { client?.Close(); } catch { }
tool.TcpClient = null; // 标记以便下次循环重建
}
}
} catch (Exception outerEx) {
Log.FunError(outerEx, MethodBase.GetCurrentMethod().Name);
}
await Task.Delay(50);
}
});
}
}
}
}