Files
RollMarking/JinYuan.Helper/JetClientHelper.cs
T
2026-09-07 08:07:08 +08:00

345 lines
12 KiB
C#
Raw 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using Newtonsoft.Json;
using JinYuan.Models;
using System.Buffers;
using System.Threading;
using Org.BouncyCastle.Ocsp;
using HslCommunication.CNC.Fanuc;
#region 命令行
//59 喷码机往外部系统发送的已喷印完成个数命令。
//60 是否开启发送已喷印完成个数命令,如果开启,喷码机每打印完一个或多个数据,就往外部系统发送一条已喷印完成个数命令,命令内容为已喷印完成个数。
//61 重置打印完成个数。
//62 读取设备唯一标识码。
//63 设置计划个数。
//64 是否开启发送打印完成内容命令,如果开启,喷码机每打印完一个或多个数据,就往外部系统发送一条打印完成数据命令,命令内容为喷印的内容。
//65 查询67号命令发送的未打印缓存数据个数。
//66 清空67号命令发送的缓存数据。
//67 修改标签内容,并将内容放置到缓存。
//68 查询已喷印完成个数。
//69 发送文件到喷码机
//70 创建新文档。
//71 设置喷印模式参数。
//72 喷码机往外部系统发送的打印完成内容命令。
//73 创建标签命令
//74 设置散喷状态
//82 修改标签内容。
//83 启动喷印。
//84 停止喷印。
//85 打开喷码机文档命令。
//86 发送图片到喷码机打印缓存
//87 查询喷码机状态
//88 喷码机向PC发送的报警信息
//89 开启、停止负压、清洗喷头、挤墨功能码
#endregion
namespace JinYuan.Helper
{
public class JetClientHelper
{
public const int BufferSize = 1024;//6kb
private int _timeout = 2000;
private Ping _ping = null;
private IPEndPoint _endPoint = null;
private Socket JetClientSocket = null;
private PingReply _pingReply = null;
public bool connectState => Connected;
/// <summary>
/// 构造函数
/// </summary>
public JetClientHelper()
{
// used to ping the PLC
//
this._ping = new Ping();
// EndPoint parametres
//
this._endPoint = new IPEndPoint(0, 0);
}
/// <summary>
/// set ip and port
/// </summary>
public void SetTCPParams(IPAddress ip, int port)
{
this._endPoint.Address = ip;
this._endPoint.Port = port;
}
/// <summary>
/// returns the connection status
/// </summary>
public bool Connected
{
get
{
try
{
return (JetClientSocket == null) ? false : JetClientSocket.Connected;
}
catch (Exception ex)
{
//PrintfLog.LogError(ex.Message);
return false;
}
}
}
/// <summary>
/// close the socket
/// </summary>
/// <returns></returns>
public void Close()
{
lock (this)
{
if (JetClientSocket == null) return;
if (Connected)
{
JetClientSocket.Disconnect(false);
JetClientSocket.Close();
}
JetClientSocket.Dispose();
JetClientSocket = null;
}
}
/// <summary>
/// 尝试多次连接喷码机,直到成功或达到最大重试次数
/// </summary>
/// <param name="maxRetryCount">最大重试次数(默认3次)</param>
/// <param name="retryDelayMs">每次重试间隔毫秒(默认50ms)</param>
/// <returns>是否最终连接成功</returns>
public bool ConnectWithRetry(int maxRetryCount = 6, int retryDelayMs = 50)
{
for (int attempt = 1; attempt <= maxRetryCount; attempt++)
{
if (this.Connect())
{
// 可选:记录成功日志
//TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now:yyyy-MM-dd}.txt",
//$"{DateTime.Now:yyyy-MM-dd HH:mm:ss} 喷码机连接成功,尝试次数:{attempt}");
return true;
}
// 如果不是最后一次尝试,则等待
if (attempt < maxRetryCount)
{
Thread.Sleep(retryDelayMs);
}
}
// 所有重试均失败
TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now:yyyy-MM-dd}.txt",
$"{DateTime.Now:yyyy-MM-dd HH:mm:ss} 喷码机连接失败,已重试{maxRetryCount}次");
return false;
}
public bool Connect()
{
try
{
if (Ping())
{
if (this.TCPConnect())
{
return true;
}
else
{
return false;
}
}
else { return false; }
}
catch (Exception ex)
{
Close();
return false;
}
}
private bool TCPConnect()
{
try
{
if (JetClientSocket != null)
{
JetClientSocket.Dispose();
}
JetClientSocket = new Socket(_endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
JetClientSocket.SendTimeout = _timeout;
JetClientSocket.ReceiveTimeout = _timeout;
JetClientSocket.Connect(this._endPoint);
return this.Connected;
}
catch (System.Exception ex)
{
return false;
}
}
public bool Ping()
{
try
{
if (this._endPoint.Address == null) { return false; }
this._pingReply = this._ping.Send(this._endPoint.Address, this._timeout);
if (this._pingReply.Status == IPStatus.Success) { return true; }
else { return false; }
}
catch (Exception)
{
//PrintfLog.LogError("ECFFU ping exception");
return false;
}
}
public bool SendAndGetRes(string json, ref JetReturnResult jet)
{
var arrayPool = ArrayPool<byte>.Shared;
byte[] RecvData = arrayPool.Rent(BufferSize);//new byte[1024];
int size = 1024;
int receiveMax = 0;
if (!Ping())
{
return false;
}
try
{
// json转bytes[]
byte[] bytes = Encoding.UTF8.GetBytes(json);
//// 发送
//JetClientSocket.Send(bytes, bytes.Length, SocketFlags.None);
//// 接收
//int response = 1024;
//string js = "";
//while (JetClientSocket.Receive(buffer) != 0 && receiveMax < 3)
//{
// js = Encoding.UTF8.GetString(buffer, 0, response);
// Thread.Sleep(100);
// receiveMax++;
//}
// 发送
Send(bytes, bytes.Length);
// 接收
Receive(ref RecvData, size);
// 解析
string js = string.Empty;
js = Encoding.UTF8.GetString(RecvData, 0, RecvData.Length);
// 找到第一个 { 和最后一个 } 的位置
int start = json.IndexOf('{');
int end = json.LastIndexOf('}');
//json反序列化
if (!string.IsNullOrEmpty(js))
{
js = json.Substring(start, end - start + 1);
jet = JsonConvert.DeserializeObject<JetReturnResult>(js);
// 处理二进制数据(如有需要)
byte[] binaryData = Encoding.ASCII.GetBytes(json.Substring(end + 1));
}
else
{
// 异常ref jet
jet.KEY = "";
jet.DATA = jet.DATA;
jet.RS = "TIMEOUT";
TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now.ToString("yyyy-MM-dd")}.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + $"喷码机数据收发超时,发送json:{json}");
}
//JetClientSocket.
//关闭socket
//JetClientSocket.Shutdown(SocketShutdown.Both);
//JetClientSocket.Close();
}
catch (Exception ex)
{
TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now.ToString("yyyy-MM-dd")}.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + $"喷码机返回原始数据:{string.Join(" ", RecvData)}");
TxtHelper.WriteTxt($@"D:\APILog\Logs\喷码机信息\{DateTime.Now.ToString("yyyy-MM-dd")}.txt", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + $"喷码机数据收发异常,原因:{ex}");
// 异常ref jet
jet.KEY = "";
jet.DATA = jet.DATA;
jet.RS = "ERROR";
Close();
return false;
}
finally
{
arrayPool.Return(RecvData);
}
return true;
}
/// <summary>
/// send a command to energy meter device
/// </summary>
/// <param name="command"></param>
/// <param name="cmdLen"></param>
/// <returns></returns>
private int Send(Byte[] command, int cmdLen)
{
if (!Connected)
{
throw new Exception("JetMachine Socket is not connected.");
}
// sends the command
//
int bytesSent = JetClientSocket.Send(command, cmdLen, SocketFlags.None);
// it checks the number of bytes sent
//
if (bytesSent != cmdLen)
{
string msg = string.Format("JetMachine Sending error. (Expected bytes: {0} Sent: {1})", cmdLen, bytesSent);
throw new Exception(msg);
}
return bytesSent;
}
/// <summary>
/// receives a response from the plc
/// </summary>
/// <param name="response"></param>
/// <param name="respLen"></param>
/// <returns></returns>
private int Receive(ref Byte[] response, int respLen)
{
if (!this.Connected)
{
throw new Exception("JetMachine Socket is not connected.");
}
// receives the response, this is a synchronous method and can hang the process
int bytesRecv = JetClientSocket.Receive(response, respLen, SocketFlags.None);
// check the number of bytes received
//
// if (bytesRecv != respLen)
// {
// string msg = string.Format("Receiving error. (Expected: {0} Received: {1})"
// , respLen, bytesRecv);
// throw new Exception(msg);
// }
return bytesRecv;
}
}
}