2026-06-05 13:44:39 +09:00

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;
}
}
}