using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace EPD.Data
{
public class SocketClientWrapper : IDisposable
{
public Action OnConnected;
public Action OnDisconnected;
public Action OnDataChanged;
private static Object _lockerSender = new Object();
private BlockingCollection SetPointCommandQueue = new BlockingCollection();
Timer timer = new Timer(500);
public class ClientStateObject
{
public const int BufferSize = 16384;
public Socket WorkSocket = null;
public byte[] CacheBufferByteData = new byte[BufferSize];
}
private Socket socket;
public bool IsConnected { get { return socket != null && socket.Connected; } }
public SocketClientWrapper()
{
timer.Elapsed += Timer_Elapsed;
timer.Enabled = true;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (SetPointCommandQueue.Count > 0)
{
var byteData = SetPointCommandQueue.Take();
socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), socket);
}
}
~SocketClientWrapper()
{
Dispose();
}
///
///
///
/// 127.0.0.1:15000
public void Connect(string ip, int port)
{
try
{
var remote = new IPEndPoint(IPAddress.Parse(ip), port);
Dispose();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.BeginConnect(remote, ConnectCallback, socket);
//Task.Run(() =>
//{
// while (SetPointCommandQueue.Count > 0)
// {
// System.Threading.Thread.Sleep(500);
// }
// System.Threading.Thread.Sleep(500);
//});
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write("Error in Connect, " + ex.Message);
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
client.EndConnect(ar);
if (OnConnected != null)
OnConnected();
System.Diagnostics.Trace.Write("Connected");
var state = new ClientStateObject();
state.WorkSocket = socket;
socket.BeginReceive(state.CacheBufferByteData, 0, ClientStateObject.BufferSize, 0, ReceiveCallback, state);
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write("Error in ConnectCallback, " + ex.Message);
}
}
public void Disconnect()
{
Dispose();
if (OnDisconnected != null)
OnDisconnected();
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
if (!IsConnected)
return;
ClientStateObject state = (ClientStateObject)ar.AsyncState;
Socket client = state.WorkSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
if (OnDataChanged != null)
OnDataChanged(state.CacheBufferByteData, 0, bytesRead);
client.BeginReceive(state.CacheBufferByteData, 0, ClientStateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write("Error in ReceiveCallback, " + ex.Message);
Disconnect();
}
}
public bool Send(byte[] byteData)
{
try
{
if (!IsConnected)
return false;
lock (_lockerSender)
{
SetPointCommandQueue.Add(byteData);
//socket.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), socket);
}
return true;
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write("Error int Write, " + ex.Message);
}
return false;
}
private void SendCallback(IAsyncResult ar)
{
try
{
lock (_lockerSender)
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write("Error in SendCallback, " + ex.Message);
}
}
public void Dispose()
{
try
{
if (socket != null)
{
if (IsConnected)
{
socket.Shutdown(SocketShutdown.Both);
}
socket.Close();
socket.Dispose();
socket = null;
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.Write("Error in Dispose, " + ex.Message);
}
}
}
}