2024-05-17 10:37:55 +00:00
|
|
|
|
using InSituLaboratory.Entities;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
|
|
namespace InSituLaboratory.Common
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 客户端
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class ClientModel : NotifyBase
|
|
|
|
|
|
{
|
|
|
|
|
|
SocketInfo SI = new SocketInfo();
|
|
|
|
|
|
|
|
|
|
|
|
public Client _client { set; get; } = new Client();
|
|
|
|
|
|
|
|
|
|
|
|
private DataParsing dataParsing { set; get; } = new DataParsing();
|
|
|
|
|
|
|
|
|
|
|
|
private bool isConnected;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Socket通信是否连接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool IsConnected
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return isConnected; }
|
|
|
|
|
|
set { isConnected = value; this.DoNotify(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 打开客户端连接
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ip"></param>
|
|
|
|
|
|
/// <param name="port"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public bool DoConnect(SocketInfo socketInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
SI.IP = socketInfo.IP;
|
|
|
|
|
|
SI.Port = socketInfo.Port;
|
|
|
|
|
|
|
|
|
|
|
|
_client.InitSocket(socketInfo.IP, socketInfo.Port); //初始化设备的IP和端口号
|
|
|
|
|
|
IsConnected = _client.Connect();
|
|
|
|
|
|
if (IsConnected)
|
|
|
|
|
|
{
|
|
|
|
|
|
_client.pushSockets = ReceiveMess;
|
2024-05-20 10:46:43 +00:00
|
|
|
|
tools.Logging("连接客户端成功,IP:" + socketInfo.IP + ",端口号:" + socketInfo.Port);
|
2024-05-17 10:37:55 +00:00
|
|
|
|
//开始进行心跳包检查
|
|
|
|
|
|
//将是否接收到心跳包判断位 置于false
|
|
|
|
|
|
IsReturnMsg = System.DateTime.Now;
|
|
|
|
|
|
//检测当前连接状态
|
2024-05-20 10:46:43 +00:00
|
|
|
|
//CheckConnect();
|
2024-05-17 10:37:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2024-05-20 10:46:43 +00:00
|
|
|
|
tools.Logging("连接客户端失败,IP:" + socketInfo.IP + ",端口号:" + socketInfo.Port);
|
2024-05-17 10:37:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
return IsConnected;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool DisConnect()
|
|
|
|
|
|
{
|
|
|
|
|
|
_client.Stop();
|
|
|
|
|
|
IsConnected = false;
|
|
|
|
|
|
return IsConnected;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region Socket通信接收
|
|
|
|
|
|
private void ReceiveMess(Sockets sks)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (sks.ex != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (sks.ClientDispose == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
//由于未知原因引发异常.导致客户端下线. 比如网络故障.或服务器断开连接.
|
|
|
|
|
|
//SetClientState(string.Format("客户端下线.!异常消息:{0}\r\n", sks.ex));
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
//SetClientState(string.Format("异常消息:{0}\r\n", sks.ex));
|
|
|
|
|
|
}
|
|
|
|
|
|
//timerConnect.Enabled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (sks.Offset == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
//客户端主动下线
|
|
|
|
|
|
// SetClientState("客户端下线.!");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
byte[] buffer = new byte[sks.Offset];
|
|
|
|
|
|
Array.Copy(sks.RecBuffer, buffer, sks.Offset);
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
dataParsing.ParsingData(new List<byte>(buffer));
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 发送消息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void SendData(byte[] SendData)
|
|
|
|
|
|
{
|
|
|
|
|
|
_client.SendData(SendData);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//用于记录心跳包的返回时间
|
|
|
|
|
|
public DateTime IsReturnMsg = System.DateTime.Now;
|
|
|
|
|
|
//用于记录当前是否在检查连接状态 初始值为false
|
|
|
|
|
|
bool IsCheckConnect = false;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用于检查当前连接状态
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private async void CheckConnect()
|
|
|
|
|
|
{
|
|
|
|
|
|
await Task.Run(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
//将检查连接状态置为开
|
|
|
|
|
|
IsCheckConnect = true;
|
|
|
|
|
|
//连接成功等待10秒后 发送心跳包
|
|
|
|
|
|
Thread.Sleep(10000);
|
|
|
|
|
|
tools.Logging("开始发送心跳包");
|
|
|
|
|
|
while ((System.DateTime.Now - IsReturnMsg).TotalSeconds < 150)
|
|
|
|
|
|
{
|
|
|
|
|
|
//发送一次Get
|
|
|
|
|
|
SendData(new byte[] { (byte)'G', (byte)'E', (byte)'T' });
|
|
|
|
|
|
tools.Logging("发送一次心跳包GET,上一次收到心跳包的时间差为" + (System.DateTime.Now - IsReturnMsg).TotalSeconds + "秒");
|
|
|
|
|
|
//等待30秒钟
|
|
|
|
|
|
Thread.Sleep(30000);
|
|
|
|
|
|
}
|
|
|
|
|
|
tools.Logging("心跳包超时,主动断开链接,停止发送心跳包GET");
|
|
|
|
|
|
//先断开链接
|
|
|
|
|
|
DisConnect();
|
|
|
|
|
|
//等待2秒钟
|
|
|
|
|
|
Thread.Sleep(2000);
|
|
|
|
|
|
tools.Logging("心跳包超时,开始初始化并重新链接!");
|
|
|
|
|
|
//重新链接
|
|
|
|
|
|
while (!DoConnect(SI))
|
|
|
|
|
|
{
|
|
|
|
|
|
tools.Logging("心跳包超时,重新链接失败!");
|
|
|
|
|
|
Thread.Sleep(30000);
|
|
|
|
|
|
}
|
|
|
|
|
|
tools.Logging("心跳包超时,重新链接成功!");
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class SocketInfo : NotifyBase
|
|
|
|
|
|
{
|
|
|
|
|
|
private string ip;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// IP
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string IP
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return ip; }
|
|
|
|
|
|
set { ip = value; this.DoNotify(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int port;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 端口号
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Port
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return port; }
|
|
|
|
|
|
set { port = value; this.DoNotify(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private string connectionmessage;
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 连接状态
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string ConnectionMessage
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return connectionmessage; }
|
|
|
|
|
|
set { connectionmessage = value; this.DoNotify(); }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|