269 lines
8.3 KiB
C#
269 lines
8.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using JWH;
|
|
using TIBCO.Rendezvous;
|
|
|
|
namespace JWH.TIB
|
|
{
|
|
|
|
public class ListenerInfo : IDisposable
|
|
{
|
|
|
|
public static int NextID = 1;
|
|
|
|
#region [ Event ] =====================================================
|
|
|
|
public delegate void OnReceivedHandler(ListenerInfo sender, MessageReceivedEventArgs args);
|
|
|
|
public delegate void OnEventHandler(ListenerInfo sender, TibRendezvousEventArgs args);
|
|
|
|
|
|
public event OnReceivedHandler OnReceivedMessage;
|
|
|
|
public event OnEventHandler OnReceivedEvent;
|
|
|
|
#endregion
|
|
|
|
#region [ Properties ] ================================================
|
|
|
|
public int ID { get; protected set; } = 0;
|
|
|
|
public XLogger Logger { get; set; } = XLogger.Instance;
|
|
|
|
public string Name { get; set; } = string.Empty;
|
|
|
|
public string Subject { get; set; } = string.Empty;
|
|
|
|
public Listener Listener { get; set; } = null;
|
|
|
|
public Queue Queue { get { return this?.Listener?.Queue; } }
|
|
|
|
protected Dispatcher Dispatcher { get; set; } = null;
|
|
|
|
protected Thread QueueDispatchThread { get; set; } = null;
|
|
|
|
protected bool QueueDispatchFlag { get; set; } = false;
|
|
|
|
protected double DispatchInterval { get; set; } = -1;
|
|
|
|
#endregion
|
|
|
|
#region [ Constructor ] ===============================================
|
|
|
|
public ListenerInfo()
|
|
{
|
|
this.ID = NextID++;
|
|
}
|
|
|
|
~ListenerInfo()
|
|
{
|
|
this.Dispose();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
try
|
|
{
|
|
if (this.Dispatcher != null)
|
|
{
|
|
this.Dispatcher.Destroy();
|
|
this.Dispatcher = null;
|
|
}
|
|
|
|
if (this.QueueDispatchThread != null)
|
|
{
|
|
this.QueueDispatchFlag = false;
|
|
if (this.QueueDispatchThread.ThreadState != ThreadState.Stopped) this.QueueDispatchThread.Abort();
|
|
this.QueueDispatchThread = null;
|
|
}
|
|
|
|
if (this.Listener != null)
|
|
{
|
|
this.Listener.Destroy();
|
|
this.Listener = null;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.Logger.Fatal(ex);
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region [ Method ] ====================================================
|
|
|
|
protected void Raise_ReceivedData(MessageReceivedEventArgs args)
|
|
{
|
|
this.OnReceivedMessage?.Invoke(this, args);
|
|
}
|
|
|
|
protected void Raise_ReceivedEvent(TibRendezvousEventArgs args)
|
|
{
|
|
this.OnReceivedEvent?.Invoke(this, args);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 비정상 종료시, 내부 쓰레드가 종료되지 않는다.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public bool Dispatch()
|
|
{
|
|
try
|
|
{
|
|
if (this.Listener == null) return false;
|
|
if (this.Listener.Queue == null) return false;
|
|
if (this.QueueDispatchThread != null) return false;
|
|
|
|
this.Dispatcher = new Dispatcher(this.Listener.Queue);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Queue.Dispatch() or Queue.TimedDispatch(interval)
|
|
/// </summary>
|
|
/// <param name="interval"></param>
|
|
/// <returns></returns>
|
|
public bool QueueDispatch(double interval = -1)
|
|
{
|
|
try
|
|
{
|
|
if (this.Listener == null) return false;
|
|
if (this.Listener.Queue == null) return false;
|
|
if (this.Dispatcher != null) return false;
|
|
this.DispatchInterval = interval;
|
|
|
|
if (this.QueueDispatchThread != null) this.QueueDispatchThread.Abort();
|
|
this.QueueDispatchThread = new Thread(new ThreadStart(this.QueueDispatch_Threading));
|
|
this.QueueDispatchThread.IsBackground = true;
|
|
this.QueueDispatchThread.Start();
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
protected void QueueDispatch_Threading()
|
|
{
|
|
try
|
|
{
|
|
this.Logger.Debug($"Start {this.Subject}");
|
|
this.QueueDispatchFlag = true;
|
|
while (this.QueueDispatchFlag)
|
|
{
|
|
try
|
|
{
|
|
if (this.DispatchInterval > 0) this.Queue.TimedDispatch(this.DispatchInterval);
|
|
else this.Queue.Dispatch();
|
|
//this.Logger.Info($"Queue.Count is {this.Queue.Count}");
|
|
}
|
|
catch (RendezvousException ex)
|
|
{
|
|
this.Logger.Fatal(ex);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
this.Logger.Fatal(ex);
|
|
}
|
|
}
|
|
this.QueueDispatchFlag = false;
|
|
this.QueueDispatchThread = null;
|
|
this.Logger.Debug($"Finish");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Tread Exception...!
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
public virtual void ReceivedMessage(object sender, MessageReceivedEventArgs eventArgs)
|
|
{
|
|
this.Raise_ReceivedData(eventArgs);
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
public class TibRendezvousEventArgs : EventArgs
|
|
{
|
|
|
|
public Message Message { get; private set; } = null;
|
|
|
|
public string SendSubject { get; private set; } = string.Empty;
|
|
|
|
public string ReplySubject { get; private set; } = string.Empty;
|
|
|
|
public string Class { get; private set; } = string.Empty;
|
|
|
|
public string Source { get; private set; } = string.Empty;
|
|
|
|
public string Name { get; private set; } = string.Empty;
|
|
|
|
public Dictionary<string, object> Properties { get; private set; } = new Dictionary<string, object>();
|
|
|
|
public TibRendezvousEventArgs()
|
|
{
|
|
}
|
|
|
|
public TibRendezvousEventArgs(Message message)
|
|
{
|
|
this.Message = message;
|
|
this.SendSubject = message.SendSubject;
|
|
this.ReplySubject = message.ReplySubject;
|
|
for (uint i = 0; i < message.FieldCount; i++)
|
|
{
|
|
MessageField field = message.GetFieldByIndex(i);
|
|
if (string.Compare(field.Name, "ADV_CLASS", true) == 0) { this.Class = field.Value.ToString(); continue; }
|
|
if (string.Compare(field.Name, "ADV_SOURCE", true) == 0) { this.Source = field.Value.ToString(); continue; }
|
|
if (string.Compare(field.Name, "ADV_NAME", true) == 0) { this.Name = field.Value.ToString(); continue; }
|
|
|
|
if (field.Value?.GetType() == typeof(DateTime))
|
|
{
|
|
DateTime dt = (DateTime)field.Value;
|
|
if (dt.Kind != DateTimeKind.Local)
|
|
{
|
|
TimeZoneInfo localZone = TimeZoneInfo.Local;
|
|
DateTime localTime = TimeZoneInfo.ConvertTimeFromUtc(dt, TimeZoneInfo.Local);
|
|
this.Properties[field.Name] = localTime;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
this.Properties[field.Name] = field.Value;
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
//sb.Append($"[{this.SendSubject}] ");
|
|
//if (!string.IsNullOrEmpty(this.ReplySubject)) sb.Append($"From {this.ReplySubject}: ");
|
|
//sb.AppendLine();
|
|
sb.Append($"ADV_CLASS='{this.Class}' ");
|
|
sb.Append($"ADV_SOURCE='{this.Source}' ");
|
|
sb.Append($"ADV_NAME='{this.Name}' ");
|
|
foreach (KeyValuePair<string, object> pair in this.Properties)
|
|
sb.Append($"({pair.Value?.GetType().Name}){pair.Key}='{pair.Value?.ToString()}' ");
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
}
|
|
|
|
}
|