using System;
|
using System.Collections.Generic;
|
using System.Net;
|
using System.Net.Sockets;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using HDL_ON.Entity;
|
using Newtonsoft.Json;
|
using Newtonsoft.Json.Linq;
|
|
namespace HDL_ON.DriverLayer
|
{
|
public class Control_TcpClient
|
{
|
|
//声明IP,端口,和一个用来连接的Socket
|
public string _ip;
|
|
private TcpClient _clinet;
|
|
private TcpClient _tcpClient {
|
get
|
{
|
return _clinet;
|
}
|
set
|
{
|
_clinet = value;
|
if (_clinet == null) {
|
if(connectThread!= null)
|
{
|
connectThread.Abort();
|
connectThread = null;
|
}
|
}
|
}
|
}
|
|
//创建一个委托,用来满足其他类调用
|
//public delegate void DelegateMessage(string str);
|
public Action<string> ReceiveEvent;
|
|
/// <summary>
|
/// 连接次数
|
/// </summary>
|
private int reconnectIndex = 0;
|
|
private bool _isConnected = false;
|
/// <summary>
|
/// 是否连接成功
|
/// </summary>
|
public bool isConnected {
|
get
|
{
|
return _isConnected;
|
}
|
set
|
{
|
_isConnected = value;
|
if (value)
|
{
|
Control.Ins.LoginGateway();
|
HeartBeat();
|
}
|
else
|
{
|
try
|
{
|
_tcpClient.Close();
|
_tcpClient = null;
|
}
|
catch (Exception)
|
{
|
|
}
|
}
|
}
|
}
|
|
private List<string> heartBeatLogIdList = new List<string>();
|
/// <summary>
|
/// 心跳记录
|
/// </summary>
|
public void ClearHeartBeatLog()
|
{
|
heartBeatLogIdList.Clear();
|
}
|
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public Control_TcpClient(string serverIp)
|
{
|
_ip = serverIp;
|
}
|
|
//TCP连接
|
private bool ConnectToTcp( )
|
{
|
if (string.IsNullOrEmpty(_ip) )
|
{
|
return false;
|
}
|
if (_tcpClient == null)
|
{
|
_tcpClient = new TcpClient();
|
}
|
try
|
{
|
_tcpClient.Connect(IPAddress.Parse(_ip), 8586);
|
ReceiveMessage();//开启线程,不停接收消息
|
MainPage.Log($"打开tcp client{_ip}:8586");
|
isConnected = true;
|
}
|
catch (Exception e)
|
{
|
MainPage.Log($"打开tcp异常:"+e.Message);
|
return false;
|
}
|
return true;//返回连接状态
|
}
|
/// <summary>
|
/// 连接tcp线程
|
/// </summary>
|
private Thread connectThread;
|
|
/// <summary>
|
/// 连接线程
|
/// </summary>
|
public void Connect()
|
{
|
lock (lockObj)
|
{
|
if (isConnected)
|
{
|
return;
|
}
|
if (connectThread == null)
|
{
|
connectThread = new Thread(() =>
|
{
|
while (Control.Ins.GatewayOnline_Local && !isConnected)
|
{
|
if (_tcpClient == null)
|
{
|
ConnectToTcp();
|
}
|
else
|
{
|
if (!_tcpClient.Connected)
|
{
|
try
|
{
|
//_tcpClient.ReceiveTimeout =
|
_tcpClient.Connect(IPAddress.Parse(_ip), 8586);
|
ReceiveMessage();//开启线程,不停接收消息
|
isConnected = true;
|
}
|
catch (Exception ex)
|
{
|
MainPage.Log($"tcp重连异常:{ex.Message}");
|
}
|
}
|
}
|
Thread.Sleep(1000);
|
|
|
}
|
});
|
connectThread.Start();
|
}
|
else
|
{
|
if (!isConnected)
|
{
|
try
|
{
|
connectThread?.Abort();
|
}
|
catch { }
|
finally
|
{
|
connectThread = null;
|
}
|
Connect();
|
}
|
}
|
}
|
}
|
/// <summary>
|
/// 重连
|
/// </summary>
|
public void Reconect()
|
{
|
if (_tcpClient == null)
|
{
|
Connect();
|
}
|
else
|
{
|
_tcpClient.Close();
|
_tcpClient = null;
|
Connect();
|
}
|
}
|
|
/// <summary>
|
/// 关闭连接
|
/// </summary>
|
/// <returns></returns>
|
public bool Close()
|
{
|
if (_tcpClient == null)
|
return true;
|
_tcpClient.Close();
|
_tcpClient = null;
|
return true;
|
}
|
|
/// <summary>
|
/// 发送消息
|
/// </summary>
|
/// <param name="bytes">需要发送的字节</param>
|
public void SendMessage(byte[] bytes)
|
{
|
if (heartBeatLogIdList.Count > 3)
|
{
|
try
|
{
|
MainPage.Log("心跳多次未回复,断开tcp连接");
|
heartBeatLogIdList.Clear();
|
isConnected = false;
|
Reconect();
|
return;
|
}catch (Exception ex)
|
{
|
MainPage.Log($"重连tcp异常:{ex.Message}");
|
}
|
}
|
try
|
{
|
if (_tcpClient.GetStream().CanWrite&& isConnected)
|
{
|
_tcpClient.GetStream().Write(bytes, 0, bytes.Length);
|
}
|
}catch(Exception ex)
|
{
|
MainPage.Log($"tcp客户端发送数据异常:{ex.Message}");
|
isConnected = false;
|
}
|
}
|
/// <summary>
|
/// 心跳包线程
|
/// </summary>
|
private Thread heartBeatThread;
|
|
private DateTime heartBeatTime;
|
public void HeartBeat()
|
{
|
lock (lockObj)
|
{
|
if (heartBeatThread == null)
|
{
|
MainPage.Log($"心跳包线程启动");
|
heartBeatThread = new Thread(() =>
|
{
|
while (isConnected)
|
{
|
if (_tcpClient.Connected && 10 * 1000 < (System.DateTime.Now - heartBeatTime).TotalMilliseconds)
|
{
|
string msgId = Control.Ins.msg_id.ToString();
|
heartBeatLogIdList.Add(msgId);
|
var sendJob = new JObject { { "id", Control.Ins.msg_id.ToString() }, { "time_stamp", Utlis.GetTimestamp() } };
|
var bodyString = JsonConvert.SerializeObject(sendJob);
|
|
var sendBytes = Control.Ins.ConvertSendBodyData(CommunicationTopic.ct.HeartBeat, bodyString, false);
|
SendMessage(sendBytes);
|
heartBeatTime = DateTime.Now;
|
}
|
Thread.Sleep(100);
|
}
|
});
|
heartBeatThread.Start();
|
}
|
else
|
{
|
try
|
{
|
heartBeatThread?.Abort();
|
}
|
catch (Exception ex)
|
{
|
MainPage.Log($"启动心跳线程,重启线程异常:{ex.Message}");
|
}
|
finally
|
{
|
if (heartBeatThread != null)
|
{
|
heartBeatThread = null;
|
}
|
HeartBeat();
|
}
|
}
|
}
|
}
|
/// <summary>
|
/// 接收数据线程
|
/// </summary>
|
private Thread receiveThread;
|
|
private object lockObj = new object();
|
|
//接收消息
|
public void ReceiveMessage()
|
{
|
lock (lockObj)
|
{
|
if (receiveThread == null)
|
{
|
receiveThread = new Thread(() =>
|
{
|
try
|
{
|
while (isConnected)
|
{
|
if (_tcpClient == null)
|
{
|
try
|
{
|
receiveThread?.Abort();
|
}
|
catch { }
|
finally
|
{
|
receiveThread = null;
|
}
|
return;
|
}
|
if (!_tcpClient.Connected)
|
{
|
MainPage.Log("tcp客户端断开了连接...");
|
isConnected = false;
|
return;
|
}
|
try
|
{
|
// 定义一个2M的缓存区;
|
byte[] arrMsgRec = new byte[1024 * 1024 * 2];
|
try
|
{
|
int size = _tcpClient.GetStream().Read(arrMsgRec, 0, arrMsgRec.Length);
|
}
|
catch (Exception ex)
|
{
|
isConnected = false;
|
MainPage.Log($"局域网tcp数据接收异常:{ex.Message}");
|
return;
|
}
|
var tcpDataString = System.Text.Encoding.UTF8.GetString(arrMsgRec, 0, arrMsgRec.Length);
|
|
|
if (!string.IsNullOrEmpty(tcpDataString))
|
{
|
MainPage.Log($"局域网tcp数据接收");
|
Control.Ins.ConvertReceiveData(arrMsgRec, null);
|
|
}
|
}
|
catch (Exception) { }
|
}
|
}catch (Exception ex)
|
{
|
MainPage.Log($"tcp ReceiveMessage error :{ex.Message}");
|
}
|
});
|
//receiveThread.IsBackground = true;
|
receiveThread.Start();
|
}
|
else
|
{
|
try
|
{
|
receiveThread?.Abort();
|
}
|
catch { }
|
finally
|
{
|
receiveThread = null;
|
ReceiveMessage();
|
}
|
}
|
}
|
}
|
|
}
|
}
|