195 lines
5.8 KiB
C#
195 lines
5.8 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Devices;
|
|
using Hermes;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Reactive.Linq;
|
|
using System.Reactive.Subjects;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
|
|
namespace AuroraDeviceCommon.Devices
|
|
{
|
|
public abstract class SocketClientDevice : Device
|
|
{
|
|
// private Config _Config;
|
|
protected readonly Logger Log;
|
|
private readonly Subject<byte[]> _Received = new Subject<byte[]>();
|
|
private object Lock = new object();
|
|
SocketConnConfig _config;
|
|
public IObservable<byte[]> Received { get; }
|
|
public Socket Client;
|
|
|
|
public int SocketNotActivatedAlarmCode { get; set; }
|
|
|
|
public SocketClientDevice(string deviceId, bool isSimul = false)
|
|
{
|
|
this.Client = null;
|
|
|
|
DeviceId = deviceId;
|
|
IsSimul = isSimul;
|
|
Log = new Logger(DeviceId);
|
|
|
|
Received = _Received.AsObservable();
|
|
|
|
}
|
|
|
|
public virtual int Send(byte[] data)
|
|
{
|
|
if (IsSimul) {
|
|
return E1.OK;
|
|
}
|
|
|
|
try {
|
|
if (!IsActivated) {
|
|
Application.Current.AuroraEnv().AlarmService.SetAlarm(SocketNotActivatedAlarmCode);
|
|
return E1.GENERIC;
|
|
}
|
|
if (Client != null) {
|
|
if (Client.Send(data) > 0) {
|
|
return E1.OK;
|
|
} else {
|
|
if (Client.Send(data) > 0) {
|
|
Log.D("Socket Send Fail. Retry Send OK");
|
|
return E1.OK;
|
|
}
|
|
}
|
|
Log.D("Socket Send Fail. Retry Send Fail");
|
|
} else {
|
|
if (Activate() == E1.OK) {
|
|
if (Client.Send(data) > 0) {
|
|
Log.D("Socket Client Retry success!!");
|
|
return E1.OK;
|
|
}
|
|
} else {
|
|
Log.D("Socket Client is Null. Re-Connect Fail.");
|
|
}
|
|
}
|
|
Log.D("Socket Send Error. Retry / Re-Connect Fail. Socket Deactivated");
|
|
//Application.Current.AuroraEnv().AlarmService.SetAlarm((int)ALARM_DEVICE.eDESC.SOCKET_DEVICE_DISCONNECTED);
|
|
DoDeactivate();
|
|
return E1.GENERIC;
|
|
} catch (Exception e) {
|
|
Log.FuncE(e.Message);
|
|
//Application.Current.AuroraEnv().AlarmService.SetAlarm((int)ALARM_DEVICE.eDESC.SOCKET_DEVICE_DISCONNECTED);
|
|
DoDeactivate();
|
|
return E1.GENERIC;
|
|
}
|
|
}
|
|
|
|
protected override int DoActivate(IDeviceConfig config)
|
|
{
|
|
int err = E1.OK;
|
|
_config = config.ConnConfig as SocketConnConfig;
|
|
if (Client == null) {
|
|
err = Connect();
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
protected override int DoDeactivate()
|
|
{
|
|
int err = E1.OK;
|
|
if (Client != null) {
|
|
err = DisConnect();
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
protected virtual byte[] ConvertStringToByte(string data)
|
|
{
|
|
return Encoding.Default.GetBytes(data);
|
|
}
|
|
|
|
protected string ConvertByteToString(byte[] data)
|
|
{
|
|
return Encoding.Default.GetString(data);
|
|
}
|
|
|
|
private int Connect()
|
|
{
|
|
if (IsSimul) {
|
|
return E1.OK;
|
|
}
|
|
try {
|
|
var endPoint = new IPEndPoint(IPAddress.Parse(_config.Address.IpAddress), _config.Address.PortNumber);
|
|
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
|
|
Client.Connect(endPoint);
|
|
if (Client.LocalEndPoint != null) {
|
|
StartReceive();
|
|
}
|
|
return E1.OK;
|
|
} catch (Exception e) {
|
|
DisConnect();
|
|
Log.FuncE(e.Message);
|
|
}
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
private void StartReceive()
|
|
{
|
|
var buffer = new Byte[1024];
|
|
try {
|
|
lock (Lock) {
|
|
if (Client != null) {
|
|
Client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveCallBack, buffer);
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
Log.FuncE(e.Message);
|
|
}
|
|
|
|
}
|
|
|
|
private void ReceiveCallBack(IAsyncResult result)
|
|
{
|
|
lock (Lock) {
|
|
if (Client == null) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
var length = 0;
|
|
try {
|
|
length = Client.EndReceive(result);
|
|
} catch (Exception e) {
|
|
Log.FuncE(e.Message);
|
|
}
|
|
|
|
var buffer = (byte[])result.AsyncState;
|
|
var data = new byte[length];
|
|
Array.Copy(buffer, data, data.Length);
|
|
_Received.OnNext(data);
|
|
|
|
StartReceive();
|
|
}
|
|
|
|
private int DisConnect()
|
|
{
|
|
if (IsSimul) {
|
|
return E1.OK;
|
|
}
|
|
try {
|
|
lock (Lock) {
|
|
Client.Shutdown(SocketShutdown.Both);
|
|
Client.Close();
|
|
Client = null;
|
|
return E1.OK;
|
|
}
|
|
} catch (Exception e) {
|
|
Client = null;
|
|
Log.FuncE(e.Message);
|
|
}
|
|
return E1.GENERIC;
|
|
}
|
|
}
|
|
}
|