345 lines
12 KiB
C#
345 lines
12 KiB
C#
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;
|
||
}
|
||
}
|
||
}
|