using Cowain.Bake.Common.Core;
using HslCommunication;
using HslCommunication.Core.Net;
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Cowain.Bake.Communication.Sokects
{
public class TcpSocketClient : NetworkXBase
{
private Encoding encoding;
private object connectLock = new object();
public string Ip { get; set; } = "127.0.0.1";
public int Port { get; set; } = 10000;
// 声明一个事件,通知变量变化
// 定义委托
public delegate void ValueChangedEventHandler(object sender, EventArgs e);
// 声明事件
public event ValueChangedEventHandler ValueChanged;
private bool _isConnected;
public bool IsConnected
{
get { return _isConnected; }
set
{
_isConnected = value;
OnValueChanged();
}
} //CoreSocket.Connected
private int bufferLength = 2048;
private byte[] buffer = null;
// 触发事件的方法
public virtual void OnValueChanged()
{
ValueChanged?.Invoke(this, EventArgs.Empty);
}
///
/// 当前的编码器
///
public Encoding Encoding
{
get
{
return encoding;
}
set
{
encoding = value;
}
}
///
/// 当接收到字符串时候的触发事件
///
public event Action ReceivedString;
///
/// 实例化一个默认的对象
///
//public TcpSocketClient()
//{
// buffer = new byte[bufferLength];
// encoding = Encoding.UTF8;
//}
///
/// 使用指定的ip地址和端口号来实例化这个对象
///
/// Ip地址
/// 端口号
public TcpSocketClient(string ipAddress, int port)
{
buffer = new byte[bufferLength];
encoding = Encoding.UTF8;
this.Ip = ipAddress;
this.Port = port;
}
///
/// 连接服务器
///
/// 返回是否连接成功
public OperateResult ConnectServer()
{
CoreSocket?.Close();
OperateResult operateResult = CreateSocketAndConnect(Ip, Port, 5000);
IsConnected = operateResult.IsSuccess;
if (!operateResult.IsSuccess)
{
return operateResult;
}
try
{
CoreSocket = operateResult.Content;
CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket);
return OperateResult.CreateSuccessResult();
}
catch (Exception ex)
{
LogHelper.Instance.Error("连接MOM系统失败!", true);
return new OperateResult(ex.Message);
}
}
///
/// 关闭当前的连接对象
///
/// 错误信息
public OperateResult ConnectClose()
{
try
{
CoreSocket?.Close();
return OperateResult.CreateSuccessResult();
}
catch (Exception ex)
{
return new OperateResult(ex.Message);
}
}
///
/// 发送字符串到网络上去
///
/// 文本信息
/// 发送是否成功
public OperateResult SendString(string text)
{
if (string.IsNullOrEmpty(text))
{
return OperateResult.CreateSuccessResult();
}
return Send(CoreSocket, encoding.GetBytes(text));
}
public OperateResult Send(byte[] text)
{
return Send(CoreSocket, text);
}
private void ReceiveCallBack(IAsyncResult ar)
{
Socket socket = ar.AsyncState as Socket;
if (socket == null)
{
return;
}
byte[] array = null;
try
{
int num = socket.EndReceive(ar);
socket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, socket);
if (num == 0)
{
IsConnected = false;
CoreSocket?.Close();
return;
}
array = new byte[num];
Array.Copy(buffer, 0, array, 0, num);
}
catch (ObjectDisposedException)
{
}
catch (Exception ex2)
{
base.LogNet?.WriteWarn(StringResources.Language.SocketContentReceiveException + ":" + ex2.Message);
ThreadPool.QueueUserWorkItem(ReConnectServer, null);
}
if (array != null)
{
this.ReceivedString?.Invoke(encoding.GetString(array));
}
}
///
/// 是否是处于重连的状态
///
/// 无用的对象
public void ReConnectServer(object obj)
{
base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerAfterTenSeconds);
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
base.LogNet?.WriteWarn($"Wait for connecting server after {9 - i} seconds");
}
OperateResult operateResult = CreateSocketAndConnect(Ip, Port, 5000);
IsConnected = operateResult.IsSuccess;
if (!operateResult.IsSuccess)
{
//用于将工作项添加到线程池的方法。它允许你将一个委托(Delegate)或方法作为参数添加到线程池中,以便由线程池中的线程执行
//ThreadPool.QueueUserWorkItem(ReConnectServer, obj); //加上它,只要一次重连就可以了,不加他,就可以执行多次。add by lsm
return;
}
lock (connectLock)
{
try
{
CoreSocket?.Close();
CoreSocket = operateResult.Content;
CoreSocket.BeginReceive(buffer, 0, bufferLength, SocketFlags.None, ReceiveCallBack, CoreSocket);
base.LogNet?.WriteWarn(StringResources.Language.ReConnectServerSuccess);
}
catch (Exception ex)
{
base.LogNet?.WriteWarn(StringResources.Language.RemoteClosedConnection + ":" + ex.Message);
ThreadPool.QueueUserWorkItem(ReConnectServer, obj);
}
}
}
///
/// 返回表示当前对象的字符串
///
/// 字符串
public override string ToString()
{
return $"NetPlainSocket[{Ip}:{Port}]";
}
}
}