초기 커밋.

This commit is contained in:
2025-02-03 11:02:48 +09:00
parent a7d46f415f
commit fe9aa0799f
2334 changed files with 674826 additions and 0 deletions

17
JWH/TIB/ListenerData.cs Normal file
View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Windows.Forms.VisualStyles;
using JWH;
using TIBCO.Rendezvous;
namespace JWH.TIB
{
public class ListenerData : ListenerInfo
{
}
}

268
JWH/TIB/ListenerInfo.cs Normal file
View File

@@ -0,0 +1,268 @@
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();
}
}
}

34
JWH/TIB/ListenerSystem.cs Normal file
View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIBCO.Rendezvous;
namespace JWH.TIB
{
public class ListenerSystem : ListenerInfo
{
public override void ReceivedMessage(object sender, MessageReceivedEventArgs eventArgs)
{
Message message = eventArgs.Message;
//StringBuilder sb = new StringBuilder();
//sb.AppendLine($"{message.ReplySubject} to {message.SendSubject}".Trim());
//for (uint i = 0; i < message.FieldCount; i++)
//{
// MessageField field = message.GetFieldByIndex(i);
// sb.AppendLine($"> {field.Name}={field.Value}");
//}
//Console.WriteLine( sb.ToString() );
TibRendezvousEventArgs args = new TibRendezvousEventArgs(message);
base.Raise_ReceivedEvent(args);
}
}
}

448
JWH/TIB/MessageParser.cs Normal file
View File

@@ -0,0 +1,448 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using JWH;
namespace JWH.TIB
{
public class MessageParser
{
public string Subject { get; set; } = string.Empty;
public string SendSubject { get; set; } = string.Empty;
public string XmlData { get; set; } = string.Empty;
public bool SendRequest { get; set; } = false;
public string PathMessageReply { get; set; } = string.Empty;
public List<MessageValue> MessageValues { get; set; } = new List<MessageValue>();
public MessageParser()
{
}
public MessageParser(string xmlData, bool sendRequest = false)
{
this.XmlData = xmlData;
this.SendRequest = sendRequest;
}
public MessageParser(string subject, string xmlData, bool sendRequest = false)
{
this.Subject = subject;
this.XmlData = xmlData;
this.SendRequest = sendRequest;
}
#region [ CreateMessage ] ----------------------------------------------
/// <summary>
/// 문자열로 XmlMessage를 생성한 후, 각 항목에 값을 설정한다
/// </summary>
/// <param name="xmlData"></param>
/// <returns></returns>
public XmlMessage CreateSendMessage(string xmlData, bool isValueSetting = true)
{
try
{
if (string.IsNullOrEmpty(xmlData)) return null;
XmlMessage xmlMessage = new XmlMessage(xmlData);
if (isValueSetting)
{
this.SetMessageValue(xmlMessage.XmlData.Header);
this.SetMessageValue(xmlMessage.XmlData.Body);
}
return xmlMessage;
}
catch (Exception ex)
{
XLogger.Instance.Fatal(ex);
return null;
}
}
/// <summary>
/// 응답메시지를 반환한다 (MessageName_*.xml)
/// </summary>
/// <param name="xmlRequest">Request Message</param>
/// <returns>Reply Message</returns>
public XmlMessage[] CreateSendReplyMessages(XmlMessage xmlRequest)
{
try
{
List<XmlMessage> lstReply = new List<XmlMessage>();
XmlMessage xmlReply = null;
string strReply = string.Empty;
// ReplyFile Processing...
DirectoryInfo directoryInfo = new DirectoryInfo(this.PathMessageReply);
foreach (FileInfo fileInfo in directoryInfo.GetFiles($"{xmlRequest.XmlData.MessageName}_*.xml"))
{
StreamReader reader = new StreamReader(fileInfo.FullName, Encoding.UTF8, true);
strReply = reader.ReadToEnd();
xmlReply = new XmlMessage(strReply);
xmlReply.SetRequstMessage(xmlRequest);
this.SetMessageValue(xmlReply.XmlData.Body, xmlRequest);
lstReply.Add(xmlReply);
}
if (lstReply.Count > 0) return lstReply.ToArray();
// Dynamic Processing
if (string.Compare(xmlRequest.XmlData.MessageName, "AreYouThereRequest", true) == 0)
xmlReply = this.CreateReply_AreYouThereRequest(xmlRequest);
else
xmlReply = this.CreateReply_Common(xmlRequest);
lstReply.Add(xmlReply);
return lstReply.ToArray();
}
catch (Exception ex)
{
XLogger.Instance.Fatal(ex);
return null;
}
}
#endregion
#region [ CreateReply ] ------------------------------------------------
/// <summary>
/// CreateReply AreYouThereRequest
/// </summary>
/// <param name="xmlRequest"></param>
/// <returns></returns>
private XmlMessage CreateReply_AreYouThereRequest(XmlMessage xmlRequest)
{
if (xmlRequest == null) return null;
XmlMessage xmlReply = new XmlMessage(xmlRequest.XmlData.GetText());
xmlReply.XmlData.MessageName += "Reply";
xmlReply.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName;
xmlReply.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName;
xmlReply.RequestMessage = xmlRequest;
if (xmlRequest.SendRequestFlag) xmlReply.IsReply = true;
return xmlReply;
}
/// <summary>
/// CreateReply Common
/// </summary>
/// <param name="xmlRequest"></param>
/// <returns></returns>
private XmlMessage CreateReply_Common(XmlMessage xmlRequest)
{
if (xmlRequest == null) return null;
XmlMessage xmlReply = new XmlMessage(xmlRequest.XmlData.GetText());
xmlReply.XmlData.SendRequestFlag = false;
xmlReply.XmlData.MessageName += "Reply";
xmlReply.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName;
xmlReply.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName;
XmlNode nodeReturn = xmlReply.XmlData.Message.CreateChildNode("return");
nodeReturn.CreateChildNode("returncode", "0");
nodeReturn.CreateChildNode("returnmessage", "TibSimulator");
xmlReply.RequestMessage = xmlRequest;
if (xmlRequest.SendRequestFlag) xmlReply.IsReply = true;
return xmlReply;
}
#endregion
#region [ Method ] ====================================================
/// <summary>
/// 메시지의 각 항목에 값을 할당한다
/// <para>Step-1. Value of srcMessage</para>
/// <para>Step-2. Value of MessageValue</para>
/// </summary>
/// <param name="node"></param>
/// <param name="srcMessage">RequestMessage</param>
private void SetMessageValue(XmlNode node, XmlMessage srcMessage = null)
{
// MessageValue(UI)
if (node.GetText() == string.Empty)
{
string name = node.Name;
XmlAttribute attribute = node.GetAttribute("Name");
if (attribute != null)
{
name = attribute.Value;
node.Attributes.Remove(attribute);
}
string srcValue = srcMessage?.XmlData.GetValue(name);
MessageValue msgValue = this.GetMessageValue(name);
if (string.IsNullOrEmpty(srcValue))
{
if (msgValue != null)
{
object value = string.Empty;
if (msgValue.Format.ToUpper() == "FUNCTION") value = this.CallFunction(node, msgValue, srcMessage);
else if (msgValue.Format.ToUpper() == "MACRO") value = this.CallMacro(node, msgValue, srcMessage);
else value = msgValue.Value;
if (value != null)
{
if (value.GetType() == typeof(string)) node.SetText((string)value);
else if (value.GetType() == typeof(XmlNode[]))
{
foreach (XmlNode child in value as XmlNode[])
node.AppendChild(child);
}
}
}
}
else
{
node.SetText(srcValue);
}
}
foreach (XmlNode child in node.ChildNodes)
{
if (child.GetType() == typeof(XmlText)) continue;
this.SetMessageValue(child, srcMessage);
}
}
/// <summary>
/// Call Function
/// </summary>
/// <param name="node"></param>
/// <param name="srcValue"></param>
/// <param name="srcMessage"></param>
/// <returns></returns>
private object CallFunction(XmlNode node, MessageValue srcValue, XmlMessage srcMessage = null)
{
try
{
string source = srcValue.Value;
string name = string.Empty;
string parameters = string.Empty;
List<object> lstParameter = new List<object>();
int length = source.Length - 1;
int indexStart = source.IndexOf('(');
int indexEnd = source.IndexOf(')');
if (indexStart >= 0) length = indexStart;
name = source.Substring(0, length);
parameters = source.Substring(indexStart + 1, indexEnd - indexStart - 1);
MethodInfo methodInfo = this.GetType().GetMethod(name);
if (methodInfo == null) return string.Empty;
lstParameter.AddRange(this.GetMethodParameters(methodInfo, node, parameters, srcMessage));
object result = methodInfo.Invoke(this, lstParameter.ToArray());
if (methodInfo.Name == "GetIncrement" && srcValue != null) srcValue.Value = $"{name}({(int)result + 1})";
return result;
}
catch (Exception ex)
{
XLogger.Instance.Fatal(ex);
return string.Empty;
}
}
/// <summary>
/// Call Macro
/// </summary>
/// <param name="node"></param>
/// <param name="srcValue"></param>
/// <param name="srcMessage"></param>
/// <returns></returns>
private object CallMacro(XmlNode node, MessageValue srcValue, XmlMessage srcMessage = null)
{
string source = srcValue.Value;
try
{
string macro = source;
string name = string.Empty;
string value = string.Empty;
int indexStart = -1;
int indexEnd = -1;
indexStart = macro.IndexOf('%', 0);
while (indexStart >= 0)
{
indexStart = macro.IndexOf('%', indexStart);
indexEnd = macro.IndexOf('%', indexStart + 1);
if (indexStart < 0) break;
name = macro.Substring(indexStart + 1, indexEnd - indexStart - 1);
value = string.Empty;
if (srcMessage != null) value = srcMessage.XmlData.GetValue(name);
if (string.IsNullOrEmpty(value))
{
MessageValue msgValue = this.GetMessageValue(name);
if (msgValue != null) value = msgValue.Value;
}
macro = $"{macro.Substring(0, indexStart)}{value}{macro.Substring(indexEnd + 1)}";
indexStart = 0;
}
return macro;
}
catch (Exception ex)
{
XLogger.Instance.Fatal(ex);
return source;
}
}
private object[] GetMethodParameters(MethodInfo method, XmlNode node, string arguments, XmlMessage srcMessage = null)
{
string[] parameters = arguments.Split(',');
List<object> lstParameter = new List<object>();
string name = string.Empty;
object value = string.Empty;
for (int i = 0; i < method.GetParameters().Length; i++)
{
if (parameters[i].StartsWith("%") && parameters[i].EndsWith("%")) name = parameters[i].Replace("%", "");
if (name.ToUpper() == "XMLNODE") { lstParameter.Add(node); continue; }
if (name.ToUpper() == "XMLMESSAGE") { lstParameter.Add(srcMessage); continue; }
if (srcMessage != null) value = srcMessage.XmlData.GetValue(name);
if (value == null || value.GetType() == typeof(string) ? string.IsNullOrEmpty((string)value) : false)
{
MessageValue msgValue = this.GetMessageValue(name);
if (msgValue != null)
{
if (msgValue.Format.ToUpper() == "FUNCTION") value = this.CallFunction(node, msgValue, srcMessage);
else if (msgValue.Format.ToUpper() == "MACRO") value = this.CallMacro(node, msgValue, srcMessage);
else value = msgValue.Value;
}
}
if (value == null) value = parameters[i];
var obj = Convert.ChangeType(value, method.GetParameters()[i].ParameterType);
lstParameter.Add(obj);
}
return lstParameter.ToArray();
}
private MessageValue GetMessageValue(string name)
{
return this.MessageValues.Where(item => item.Name.ToUpper() == name.ToUpper()).FirstOrDefault();
}
#endregion
#region [ Function Method ] ============================================
public string GetDateTime()
{
return DateTime.Now.ToString("yyyyMMddHHmmss");
}
public string GetTransactionID()
{
return Guid.NewGuid().ToString();
}
public string GetIPAddress()
{
return "127.0.0.1";
}
public object[] GetPanelList(XmlNode node, string lotID, int qty)
{
List<XmlNode> lstPanel = new List<XmlNode>();
for (int i = qty; i > 0; i--)
{
XmlNode panelInfo = node.OwnerDocument.CreateNode("element", "PANELINFO", "");
XmlNode panelID = node.OwnerDocument.CreateNode("element", "PANELID", "");
panelID.SetText($"{lotID}_{i.ToString("00")}");
XmlNode panelSeq = node.OwnerDocument.CreateNode("element", "PANELSEQ", "");
panelSeq.SetText($"{i}");
panelInfo.AppendChild(panelID);
panelInfo.AppendChild(panelSeq);
lstPanel.Add(panelInfo);
}
return lstPanel.ToArray();
}
public object[] GetChilds(XmlNode node, XmlMessage srcMessage)
{
if (srcMessage == null) return null;
List<XmlNode> lstChilid = new List<XmlNode>();
XmlNode xmlNode = srcMessage.XmlData.GetNode(node.Name);
foreach (XmlNode child in xmlNode.ChildNodes)
{
XmlNode importNode = node.OwnerDocument.ImportNode(child, true);
node.AppendChild(importNode);
}
return null;
}
public int GetIncrement(Int32 value)
{
return value;
}
public string ChangeLotID()
{
MessageValue msgValueText = this.GetMessageValue("LotText");
MessageValue msgValueSeq = this.GetMessageValue("LotSeq");
MessageValue msgValueID = this.GetMessageValue("LotID");
if (msgValueText == null || msgValueSeq == null || msgValueID == null) return String.Empty;
int seq = 0;
int.TryParse(msgValueSeq.Value, out seq);
string value = $"{msgValueText.Value}{seq.ToString("00")}";
msgValueID.Value = value;
msgValueSeq.Value = (seq + 1).ToString();
return value;
}
public string ChangeCarrierID()
{
MessageValue msgValueText = this.GetMessageValue("CarrierText");
MessageValue msgValueSeq = this.GetMessageValue("CarrierSeq");
MessageValue msgValueID = this.GetMessageValue("CarrierID");
if (msgValueText == null || msgValueSeq == null || msgValueID == null) return String.Empty;
int seq = 0;
int.TryParse(msgValueSeq.Value, out seq);
string value = $"{msgValueText.Value}{seq.ToString("00")}";
msgValueID.Value = value;
msgValueSeq.Value = (seq + 1).ToString();
return value;
}
#endregion
}
}

49
JWH/TIB/MessageValue.cs Normal file
View File

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using JWH;
namespace JWH.TIB
{
public class MessageValue
{
public string Name { get; set; } = string.Empty;
public string Value { get; set; } = string.Empty;
public string Format { get; set; } = string.Empty;
public List<string> Values { get; set; } = new List<string>();
public MethodInfo Method { get; set; } = null;
public List<string> Parameters { get; set; } = new List<string>();
public MessageValue()
{
}
public MessageValue(XmlNode node)
{
try
{
node.PropertiesCopyAttribute(this);
this.Value = node.InnerText;
}
catch (Exception ex)
{
XLogger.Instance.Fatal(ex);
}
}
public override string ToString()
{
return $"{this.Name}={this.Value}";
}
}
}

65
JWH/TIB/ServerInfo.cs Normal file
View File

@@ -0,0 +1,65 @@
using System;
using TIBCO.Rendezvous;
namespace JWH.TIB
{
/// <summary>
/// TIBCO.Rendezvous 연결정보
/// </summary>
public class ServerInfo
{
#region [ Properties ] ================================================
public TransportType TransportType { get; set; } = TransportType.Reliable;
public string GUID { get; protected set; } = string.Empty;
public string Name { get; set; } = string.Empty;
public string Service { get; set; } = string.Empty;
public string Daemon { get; set; } = string.Empty;
public string Network { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string CMName { get; set; } = string.Empty;
public bool RequestOld { get; set; } = false;
public string LedgerName { get; set; } = string.Empty;
public bool SyncLedger { get; set; } = false;
#endregion
#region [ Constructor ] ===============================================
public ServerInfo()
{
this.GUID = Guid.NewGuid().ToString();
}
public ServerInfo(string server, string service, string daemon, string network, string subject) : this()
{
this.Name = server;
this.Service = service;
this.Daemon = daemon;
this.Network = network;
}
#endregion
}
public enum TransportType
{
Reliable = 1,
Certiry = 2,
Distributed = 3,
}
}

956
JWH/TIB/TibRendezvous.cs Normal file
View File

@@ -0,0 +1,956 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Forms;
using TIBCO.Rendezvous;
using Message = TIBCO.Rendezvous.Message;
namespace JWH.TIB
{
public class TibRendezvous
{
#region [ Static ] ====================================================
private static bool IsOpen { get; set; } = false;
public static void Open(XLogger logger = null)
{
if (IsOpen) return;
try
{
IsOpen = true;
if (logger == null) logger = XLogger.Instance;
logger.Info($"TIBCO.Rendezvous.Environment.Open()");
TIBCO.Rendezvous.Environment.Open();
}
catch (Exception ex)
{
if (logger != null) logger.Fatal(ex);
throw ex;
}
}
public static void Close(XLogger logger = null)
{
if (!IsOpen) return;
try
{
IsOpen = false;
if (logger == null) logger = XLogger.Instance;
logger.Info($"TIBCO.Rendezvous.Environment.Close()");
TIBCO.Rendezvous.Environment.Close();
}
catch (Exception ex)
{
if (logger != null) logger.Fatal(ex);
throw ex;
}
}
#endregion
#region [ Event ] =====================================================
private delegate void ServiceStartHandler();
public delegate void OnTransportHandler(TibRendezvous sender, XmlMessage xmlMessage);
public delegate void OnListenerHandler(Listener sender, XmlMessage xmlMessage);
public delegate void OnListenerInfoHandler(ListenerInfo sender, XmlMessage xmlMessage);
public delegate void OnListenerInfoEventHandler(ListenerInfo sender, TibRendezvousEventArgs args);
public delegate void OnExceptionHandler(TibRendezvous sender, XmlMessage xmlMessage, Exception ex);
/// <summary>
/// Communication Started
/// </summary>
public event EventHandler OnStarted;
/// <summary>
/// Communication Stoped
/// </summary>
public event EventHandler OnStoped;
/// <summary>
/// Message Send
/// </summary>
public event OnTransportHandler OnSend;
/// <summary>
/// Message Sent
/// </summary>
public event OnTransportHandler OnSent;
/// <summary>
/// Message Received
/// </summary>
public event OnListenerInfoHandler OnReceived;
/// <summary>
/// Timeout Exception(SendRequest, SendReply)
/// </summary>
public event OnExceptionHandler OnTimeout;
/// <summary>
/// TIBCO.Rendezvous Event
/// </summary>
public event OnListenerInfoEventHandler OnEvent;
#endregion
#region [ Rendezvous.Variable ] =======================================
/// <summary>
/// Rendezvous Server Information(서버 이상 발생시, 환형구조로 다음 서버로 연결한다)
/// </summary>
public List<ServerInfo> ServerInfos { get; protected set; } = new List<ServerInfo>();
/// <summary>
/// Current Rendezvous Server Information
/// </summary>
public ServerInfo ServerInfo { get; protected set; } = null;
/// <summary>
/// Transport
/// </summary>
public Transport Transport { get; set; } = null;
/// <summary>
/// Rendezvous Listener Information
/// </summary>
public List<ListenerInfo> Listeners { get; protected set; } = new List<ListenerInfo>();
/// <summary>
/// Rendezvous Listener Information (System Event)
/// </summary>
public ListenerSystem ListenerSystem { get; set; } = null;
#endregion
#region [ Variable ] ==================================================
#endregion
#region [ Properties ] ================================================
/// <summary>
/// Logger
/// </summary>
public XLogger Logger { get; set; } = XLogger.Instance;
/// <summary>
/// 이벤트 보고시, Invoke 처리를 위한 상위객체
/// </summary>
public Control Parent { get; set; } = null;
/// <summary>
/// Message 전송시, Thread 방식을 사용할 것인지를 설정한다
/// </summary>
public bool UseThreadSend { get; set; } = true;
/// <summary>
/// 수신된 SendRequest 메시지를 보관한다
/// </summary>
public Dictionary<string, XmlMessage> SendRequestMessages { get; protected set; } = new Dictionary<string, XmlMessage>();
/// <summary>
/// SendRequest 수신후, SendReply 전송시간 (기본값: 30초)
/// </summary>
[DefaultValue(30)]
public int SendRequestTime { get; set; } = 30;
/// <summary>
/// SendRequest 전송후, SendReply 메시지 수신시간 (기본값: 30초)
/// </summary>
[DefaultValue(30)]
public int SendReplyTime { get; set; } = 30;
#endregion
#region [ Constructor ] ===============================================
public TibRendezvous()
{
}
public TibRendezvous(XLogger logger = null)
{
this.Logger = logger;
}
public TibRendezvous(ServerInfo serverInfo, XLogger logger = null) : this()
{
try
{
this.Logger = logger;
this.ServerInfo = serverInfo;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
#region [ Raise_Events ] ==============================================
private void Raise_OnStarted()
{
try
{
if (this.OnStarted == null) return;
if (this.Parent != null && this.Parent.InvokeRequired)
this.Parent.BeginInvoke(new EventHandler(this.OnStarted), this, new EventArgs());
else
this.OnStarted?.Invoke(this, new EventArgs());
}
catch (Exception ex)
{
throw ex;
}
}
private void Raise_OnStoped()
{
try
{
if (this.OnStoped == null) return;
if (this.Parent != null && this.Parent.InvokeRequired)
this.Parent.BeginInvoke(new EventHandler(this.OnStoped), this, new EventArgs());
else
this.OnStoped?.Invoke(this, new EventArgs());
}
catch (Exception ex)
{
throw ex;
}
}
private void Raise_OnSend(XmlMessage xmlMessage)
{
try
{
if (this.OnSend == null) return;
if (this.Parent != null && this.Parent.InvokeRequired)
this.Parent.BeginInvoke(new OnTransportHandler(this.OnSend), this, xmlMessage);
else
this.OnSend?.Invoke(this, xmlMessage);
}
catch (Exception ex)
{
throw ex;
}
}
private void Raise_OnSent(XmlMessage xmlMessage)
{
try
{
this.SendRequestMessage_Remove(xmlMessage);
if (this.OnSent == null) return;
if (this.Parent != null && this.Parent.InvokeRequired)
this.Parent.BeginInvoke(new OnTransportHandler(this.OnSent), this, xmlMessage);
else
this.OnSent?.Invoke(this, xmlMessage);
}
catch (Exception ex)
{
throw ex;
}
}
private void Raise_OnReceived(ListenerInfo sender, XmlMessage xmlMessage)
{
try
{
this.Logger.Info($"SendSubject='{xmlMessage.SendSubject}', ReplySubject='{xmlMessage.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
if (this.OnReceived == null) return;
if (this.Parent != null && this.Parent.InvokeRequired)
this.Parent.BeginInvoke(new OnListenerInfoHandler(this.OnReceived), sender, xmlMessage);
else
this.OnReceived?.Invoke(sender, xmlMessage);
}
catch (Exception ex)
{
throw ex;
}
}
private void Raise_OnEvent(ListenerInfo sender, TibRendezvousEventArgs args)
{
try
{
if (this.OnEvent == null) return;
if (this.Parent != null && this.Parent.InvokeRequired)
this.Parent.BeginInvoke(new OnListenerInfoEventHandler(this.OnEvent), sender, args);
else
this.OnEvent?.Invoke(sender, args);
}
catch (Exception ex)
{
throw ex;
}
}
private void Raise_OnTimeout(XmlMessage xmlMessage, Exception ex)
{
try
{
if (this.OnTimeout == null) return;
if (this.Parent != null && this.Parent.InvokeRequired)
this.Parent.BeginInvoke(new OnExceptionHandler(this.OnTimeout), this, xmlMessage, ex);
else
this.OnTimeout?.Invoke(this, xmlMessage, ex);
}
catch (Exception ex1)
{
throw ex1;
}
}
#endregion
#region [ Public Method ] =============================================
/// <summary>
/// Communication Start
/// </summary>
public void Start()
{
try
{
this.Logger.Info();
this.NextServerInfo();
if (this.ServerInfo == null) return;
TibRendezvous.Open();
ServiceStartHandler startMethod = null;
switch (this.ServerInfo.TransportType)
{
case TransportType.Reliable: startMethod = this.RMServiceStart; break;
case TransportType.Certiry: startMethod = this.CMServiceStart; break;
case TransportType.Distributed: startMethod = this.DQServiceStart; break;
}
startMethod();
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// Communication Start
/// </summary>
public void Restart()
{
try
{
this.Logger.Info();
if (this.ServerInfo == null) this.NextServerInfo();
if (this.ServerInfo == null) return;
TibRendezvous.Open();
ServiceStartHandler startMethod = null;
switch (this.ServerInfo.TransportType)
{
case TransportType.Reliable: startMethod = this.RMServiceStart; break;
case TransportType.Certiry: startMethod = this.CMServiceStart; break;
case TransportType.Distributed: startMethod = this.DQServiceStart; break;
}
startMethod();
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// Stop
/// </summary>
public void Stop()
{
this.Logger.Info();
this.ServiceStop();
}
#endregion
#region [ Method ] ====================================================
/// <summary>
/// RM ServiceStart(Reliable Message)
/// </summary>
private void RMServiceStart()
{
try
{
this.ServiceStop();
this.Logger.Info();
this.Logger.Info($"NetTransport({this.ServerInfo.Service}, {this.ServerInfo.Network}, {this.ServerInfo.Daemon})");
NetTransport netTransport = new NetTransport(this.ServerInfo.Service, this.ServerInfo.Network, this.ServerInfo.Daemon);
this.Transport = netTransport;
#region [ Event Listener : Failover ]
{
ListenerSystem listenerSys = new ListenerSystem();
listenerSys.Name = "SYSTEM";
listenerSys.Subject = $"_RV.*.*.*.*";
this.ListenerSystem = listenerSys;
Queue queue = new Queue();
queue.Name = listenerSys.Name;
Listener listener = new Listener(queue, listenerSys.ReceivedMessage, this.Transport, listenerSys.Subject, null);
this.Logger.Info($"Listener({queue.GetType().Name}, ReceivedMessage, {listener?.Transport.GetType().Name}, {listener.Subject}, null)");
listenerSys.Logger = this.Logger;
listenerSys.Listener = listener;
listenerSys.OnReceivedMessage += this.OnReceivedMessage;
listenerSys.OnReceivedEvent += this.OnReceivedEvent;
listenerSys.QueueDispatch();
}
#endregion
foreach (ListenerInfo listenerInfo in this.Listeners)
{
if (string.IsNullOrEmpty(netTransport.Description)) netTransport.Description = $"{listenerInfo.Subject}";
Queue queue = new Queue();
queue.Name = listenerInfo.Name;
Listener listener = new Listener(queue, listenerInfo.ReceivedMessage, this.Transport, listenerInfo.Subject, null);
this.Logger.Info($"Listener({queue.GetType().Name}, ReceivedMessage, {listener?.Transport.GetType().Name}, {listener.Subject}, null)");
listenerInfo.Logger = this.Logger;
listenerInfo.Listener = listener;
listenerInfo.OnReceivedMessage += this.OnReceivedMessage;
listenerInfo.OnReceivedEvent += this.OnReceivedEvent;
listenerInfo.QueueDispatch();
}
this.Raise_OnStarted();
}
catch (RendezvousException ex)
{
this.Logger.Fatal(ex);
throw ex;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
}
/// <summary>
/// CM ServiceStart(Certiry Message)
/// </summary>
private void CMServiceStart()
{
try
{
this.ServiceStop();
this.Logger.Info();
this.Logger.Info($"NetTransport({this.ServerInfo.Service}, {this.ServerInfo.Network}, {this.ServerInfo.Daemon})");
NetTransport netTransport = new NetTransport(this.ServerInfo.Service, this.ServerInfo.Network, this.ServerInfo.Daemon);
//this.Transport = netTransport;
this.Logger.Info($"CMTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
CMTransport cmTransport = new CMTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
//this.Logger.Info($"CMTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
//CMTransport cmTransport = new CMTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
this.Transport = cmTransport;
#region [ Event Listener ]
{
ListenerSystem listenerSys = new ListenerSystem();
listenerSys.Name = "SYSTEM";
listenerSys.Subject = $"_RV.*.*.*.*";
this.ListenerSystem = listenerSys;
Queue queue = new Queue();
Listener listener = new Listener(queue, listenerSys.ReceivedMessage, netTransport, listenerSys.Subject, null);
this.Logger.Info($"Listener(Queue[{queue.Name}], ReceivedMessage, {listener.Transport.GetType().ToString()}, {listener.Subject}, null)");
listenerSys.Listener = listener;
listenerSys.OnReceivedMessage += this.OnReceivedMessage;
listenerSys.OnReceivedEvent += this.OnReceivedEvent;
listenerSys.Dispatch();
}
#endregion
foreach (ListenerInfo listenerInfo in this.Listeners)
{
Queue queue = new Queue();
CMListener listener = new CMListener(queue, listenerInfo.ReceivedMessage, cmTransport, listenerInfo.Subject, null);
this.Logger.Info($"CMListener(Queue[{queue.Name}], ReceivedMessage, {listener.Transport.GetType().ToString()}, {listener.Subject}, null)");
listenerInfo.Listener = listener;
listenerInfo.OnReceivedMessage += this.OnReceivedMessage;
listenerInfo.OnReceivedEvent += this.OnReceivedEvent;
listenerInfo.Dispatch();
}
this.Raise_OnStarted();
}
catch (RendezvousException ex)
{
this.Logger.Fatal(ex);
throw ex;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
}
/// <summary>
/// Distributed ServiceStart(Distributed Queue)
/// </summary>
private void DQServiceStart()
{
try
{
this.ServiceStop();
this.Logger.Info();
this.Logger.Info($"NetTransport({this.ServerInfo.Service}, {this.ServerInfo.Network}, {this.ServerInfo.Daemon})");
NetTransport netTransport = new NetTransport(this.ServerInfo.Service, this.ServerInfo.Network, this.ServerInfo.Daemon);
this.Transport = netTransport;
//this.Logger.Info($"CMTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
//CMTransport cmTransport = new CMTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
//this.Transport = cmTransport;
this.Logger.Info($"CMQueueTransport(CMTransport, {this.ServerInfo.CMName})");
CMQueueTransport cmqTransport = new CMQueueTransport(netTransport, this.ServerInfo.CMName, 1, 5, 1, 1.0, 1.5);
//this.Logger.Info($"CMQueueTransport(NetTransport, {this.ServerInfo.CMName}, {this.ServerInfo.RequestOld}, {this.ServerInfo.LedgerName}, {this.ServerInfo.SyncLedger})");
//CMQueueTransport cmqTransport = new CMQueueTransport(netTransport, this.ServerInfo.CMName, this.ServerInfo.RequestOld, this.ServerInfo.LedgerName, this.ServerInfo.SyncLedger);
#region [ Event Listener ]
{
ListenerSystem listenerSys = new ListenerSystem();
listenerSys.Name = "SYSTEM";
listenerSys.Subject = $"_RV.*.*.*.*";
this.ListenerSystem = listenerSys;
Queue queue = new Queue();
Listener listener = new Listener(queue, listenerSys.ReceivedMessage, netTransport, listenerSys.Subject, null);
this.Logger.Info($"{listener.GetType().Name}(Queue[{queue.Name}], ReceivedMessage, {listener.Transport.GetType().ToString()}, {listener.Subject}, null)");
listenerSys.Listener = listener;
listenerSys.OnReceivedMessage += this.OnReceivedMessage;
listenerSys.OnReceivedEvent += this.OnReceivedEvent;
listenerSys.Dispatch();
}
#endregion
foreach (ListenerInfo listenerInfo in this.Listeners)
{
Queue queue = new Queue();
CMListener cmListener = new CMListener(queue, listenerInfo.ReceivedMessage, cmqTransport, listenerInfo.Subject, null);
this.Logger.Info($"{cmListener.GetType().Name}(Queue[{queue.Name}], ReceivedMessage, {cmListener.Transport.GetType().ToString()}, {cmListener.Subject}, null)");
listenerInfo.Listener = cmListener;
listenerInfo.OnReceivedMessage += this.OnReceivedMessage;
listenerInfo.OnReceivedEvent += this.OnReceivedEvent;
listenerInfo.Dispatch();
}
this.Raise_OnStarted();
}
catch (RendezvousException ex)
{
this.Logger.Fatal(ex);
throw ex;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
}
/// <summary>
/// ServiceStop
/// </summary>
private void ServiceStop()
{
try
{
this.Logger.Info();
if (this.ListenerSystem != null)
{
this.ListenerSystem.Listener?.Transport?.Destroy();
this.ListenerSystem.OnReceivedMessage -= this.OnReceivedMessage;
this.ListenerSystem.OnReceivedEvent -= this.OnReceivedEvent;
this.ListenerSystem.Dispose();
}
foreach(ListenerInfo listenerInfo in this.Listeners)
{
this.Logger.Debug($"Listener[{listenerInfo.Subject}].Dispose");
listenerInfo.Listener?.Transport?.Destroy();
listenerInfo.OnReceivedMessage -= this.OnReceivedMessage;
listenerInfo.OnReceivedEvent -= this.OnReceivedEvent;
listenerInfo.Dispose();
}
if (this.Transport != null)
{
this.Logger.Debug($"Transport.Destroy()");
this.Transport.Destroy();
this.Transport = null;
this.Raise_OnStoped();
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// Received Data(XmlData)
/// </summary>
/// <param name="sender"></param>
/// <param name="eventArgs"></param>
public void OnReceivedMessage(ListenerInfo sender, MessageReceivedEventArgs args)
{
try
{
Listener listener = sender.Listener;
Message message = args.Message;
XmlMessage xmlMessage = new XmlMessage(message);
this.SendRequestMessage_Add(xmlMessage);
this.Raise_OnReceived(sender, xmlMessage);
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
}
}
/// <summary>
/// Add SendRequestMessage
/// </summary>
/// <param name="xmlMessage"></param>
private void SendRequestMessage_Add(XmlMessage xmlMessage)
{
try
{
if (string.IsNullOrEmpty(xmlMessage.XmlData.TransactionID)) return;
if (this.SendRequestMessages == null) return;
if (this.SendRequestMessages.ContainsKey(xmlMessage.XmlData.TransactionID)) return;
bool isAdd = false;
// 1. SendRequest() --> SendReply()
if (!string.IsNullOrEmpty(xmlMessage.Message.ReplySubject)) isAdd = true;
// 2. SendRequestFlag is True --> Send()
//if (xmlMessage.SendRequestFlag) isAdd = true;
if (isAdd == false) return;
this.SendRequestMessages.Add(xmlMessage.XmlData.TransactionID, xmlMessage);
xmlMessage.OnTimeOver += this.SendRequest_OnTimeover;
xmlMessage.TimerStart(this.SendRequestTime);
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
}
}
/// <summary>
/// Remove SendRequestMessage
/// </summary>
/// <param name="xmlMessage"></param>
private void SendRequestMessage_Remove(XmlMessage xmlMessage)
{
try
{
if (string.IsNullOrEmpty(xmlMessage.XmlData.TransactionID)) return;
if (this.SendRequestMessages == null) return;
if (!this.SendRequestMessages.ContainsKey(xmlMessage.XmlData.TransactionID)) return;
XmlMessage message = this.SendRequestMessages[xmlMessage.XmlData.TransactionID];
message.OnTimeOver -= this.SendRequest_OnTimeover;
message.TimerStop();
this.SendRequestMessages.Remove(xmlMessage.XmlData.TransactionID);
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
}
}
/// <summary>
/// SendRequest 수신후, SendReply를 전송하지 않았을 경우 호출된다
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SendRequest_OnTimeover(object sender, EventArgs e)
{
XmlMessage xmlMessage = sender as XmlMessage;
if (xmlMessage == null) return;
if (this.SendRequestMessages.ContainsKey(xmlMessage.XmlData.TransactionID))
this.SendRequestMessages.Remove(xmlMessage.XmlData.TransactionID);
this.Raise_OnTimeout(xmlMessage, new Exception(Source.S10001) { Source = "S10001" });
}
/// <summary>
/// Received Event
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public void OnReceivedEvent(ListenerInfo sender, TibRendezvousEventArgs args)
{
try
{
this.Logger.Debug(args.ToString());
this.Raise_OnEvent(sender, args);
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
}
}
/// <summary>
/// ServerInfo에 접속정보를 할당한다
/// </summary>
/// <returns></returns>
private ServerInfo NextServerInfo()
{
if (this.ServerInfos.Count == 0) return null;
if (this.ServerInfo == null)
{
this.ServerInfo = this.ServerInfos[0];
return this.ServerInfo;
}
int index = this.ServerInfos.IndexOf(this.ServerInfo);
if (index == -1) index = 0;
else index += 1;
if (index >= this.ServerInfos.Count) index = 0;
this.ServerInfo = this.ServerInfos[index];
return this.ServerInfo;
}
#endregion
#region [ SendMessage ] ===============================================
public XmlMessage SendMessage(XmlMessage xmlMessage, OnTransportHandler callback = null)
{
XmlMessage response = null;
try
{
if (xmlMessage == null) return response;
if (xmlMessage.IsReply && !string.IsNullOrEmpty(xmlMessage?.RequestMessage?.ReplySubject)) this.SendReply(xmlMessage, callback);
else if (xmlMessage.SendRequestFlag) response = this.SendRequest(xmlMessage, callback);
else this.Send(xmlMessage, callback);
return response;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
}
public XmlMessage SendRequest(XmlMessage xmlMessage, OnTransportHandler callback = null)
{
XmlMessage xmlResponse = null;
try
{
xmlMessage.SendRequestFlag = true;
Message message = xmlMessage.Message;
this.Raise_OnSend(xmlMessage);
if (this.UseThreadSend)
{
Task.Factory.StartNew(delegate ()
{
try
{
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
Message response = this.Transport.SendRequest(message, this.SendReplyTime);
this.Raise_OnSent(xmlMessage);
if (response == null)
{
this.Raise_OnTimeout(xmlMessage, new Exception(Source.S10002) { Source = "S10002" });
return;
}
xmlResponse = new XmlMessage(response) { RequestMessage = xmlMessage, IsReply = true };
this.Raise_OnReceived(null, xmlResponse);
if (callback != null) callback(this, xmlResponse);
}
catch (RendezvousException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
});
}
else
{
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
Message response = this.Transport.SendRequest(message, this.SendReplyTime);
this.Raise_OnSent(xmlMessage);
if (response == null)
{
this.Raise_OnTimeout(xmlMessage, new Exception(Source.S10002) { Source = "S10002" });
return xmlResponse;
}
xmlResponse = new XmlMessage(response) { RequestMessage = xmlMessage, IsReply = true };
this.Raise_OnReceived(null, xmlResponse);
if (callback != null) callback(this, xmlResponse);
}
}
catch (RendezvousException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
return xmlResponse;
}
public void SendReply(XmlMessage xmlMessage, OnTransportHandler callback = null)
{
try
{
Message reply = xmlMessage.Message;
XmlMessage request = xmlMessage.RequestMessage;
this.Raise_OnSend(xmlMessage);
if (this.UseThreadSend)
{
Task.Factory.StartNew(delegate ()
{
try
{
this.Logger.Debug($"SendSubject='{reply.SendSubject}', ReplySubject='{reply.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
this.Transport.SendReply(reply, request.Message);
this.Raise_OnSent(xmlMessage);
if (callback != null) callback(this, xmlMessage);
}
catch (RendezvousException ex)
{
this.Logger.Fatal(ex);
throw ex;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
});
}
else
{
this.Logger.Debug($"SendSubject='{reply.SendSubject}', ReplySubject='{reply.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
this.Transport.SendReply(reply, request.Message);
this.Raise_OnSent(xmlMessage);
if (callback != null) callback(this, xmlMessage);
}
}
catch (RendezvousException ex)
{
this.Logger.Fatal(ex);
throw ex;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
}
public void Send(XmlMessage xmlMessage, OnTransportHandler callback = null)
{
try
{
Message message = xmlMessage.Message;
this.Raise_OnSend(xmlMessage);
if (this.UseThreadSend)
{
try
{
Task.Factory.StartNew(delegate ()
{
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
this.Transport.Send(message);
this.Raise_OnSent(xmlMessage);
if (callback != null) callback(this, xmlMessage);
});
}
catch (RendezvousException ex)
{
this.Logger.Fatal(ex);
throw ex;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
}
else
{
this.Logger.Debug($"SendSubject='{message.SendSubject}', ReplySubject='{message.ReplySubject}', SendRequestFlag='{xmlMessage.SendRequestFlag}'");
this.Transport.Send(message);
this.Raise_OnSent(xmlMessage);
if (callback != null) callback(this, xmlMessage);
}
}
catch (RendezvousException ex)
{
this.Logger.Fatal(ex);
throw ex;
}
catch (Exception ex)
{
this.Logger.Fatal(ex);
throw ex;
}
}
#endregion
}
public static class Source
{
public const string S10001 = "SendRequest Timeout: SendReply 메시지를 지정된 시간내에 전송하지 못하였습니다";
public const string S10002 = "SendReply Timeout: SendReply 메시지를 지정된 시간내에 수신하지 못하였습니다";
}
}

333
JWH/TIB/XmlData.cs Normal file
View File

@@ -0,0 +1,333 @@
using System;
using System.Xml;
using JWH;
namespace JWH.TIB
{
public class XmlData
{
#region [ Variable ] ==================================================
private XmlDocument Document { get; set; } = null;
#endregion
#region [ Properties ] ================================================
public bool SendRequestFlag { get; set; } = false;
public XmlNode Message { get; set; } = null;
public XmlNode Header { get; set; } = null;
public XmlNode Body { get; set; } = null;
#region [ Header Items ] -----------------------------------------------
/// <summary>
/// Header.MessageName
/// </summary>
public string MessageName
{
get { return this.GetValue("MessageName"); }
set { this.SetValue("MessageName", value); }
}
/// <summary>
/// Header.TransationID
/// </summary>
public string TransactionID
{
get { return this.GetValue("TransactionID"); }
set { this.SetValue("TransactionID", value); }
}
/// <summary>
/// Header.SendSubjectName
/// </summary>
public string SendSubjectName
{
get { return this.GetValue("SendSubjectName"); }
set { this.SetValue("SendSubjectName", value); }
}
/// <summary>
/// Header.ReplySubjectName
/// </summary>
public string ReplySubjectName
{
get { return this.GetValue("ReplySubjectName"); }
set { this.SetValue("ReplySubjectName", value); }
}
#endregion
#region [ Body Items ] -------------------------------------------------
/// <summary>
/// Body.SITEID
/// </summary>
public string SITEID
{
get { return this.GetValue("SITEID"); }
set { this.SetValue("SITEID", value); }
}
/// <summary>
/// Body.EquipmentID
/// </summary>
public string EquipmentID
{
get { return this.GetValue("EquipmentID"); }
set { this.SetValue("EquipmentID", value); }
}
/// <summary>
/// Body.DateTime
/// </summary>
public string DateTime
{
get { return this.GetValue("DateTime"); }
set { this.SetValue("DateTime", value); }
}
/// <summary>
/// Body.ControlMode
/// </summary>
public string ControlMode
{
get { return this.GetValue("ControlMode"); }
set { this.SetValue("ControlMode", value); }
}
#endregion
#region [ Return Items ] -----------------------------------------------
/// <summary>
/// Return.ReturnCode
/// </summary>
public string ReturnCode
{
get { return this.GetValue("ReturnCode"); }
set { this.SetValue("ReturnCode", value); }
}
/// <summary>
/// Return.ReturnMessage
/// </summary>
public string ReturnMessage
{
get { return this.GetValue("ReturnMessage"); }
set { this.SetValue("ReturnMessage", value); }
}
#endregion
#endregion
#region [ Constructor ] ===============================================
public XmlData()
{
if (this.Document == null) this.Document = new XmlDocument();
XmlDocument document = this.Document;
XmlNode node = null;
this.Message = document.CreateNode("element", "message", "");
document.AppendChild(this.Message);
this.Header = document.CreateNode("element", "header", "");
this.Message.AppendChild(this.Header);
node = document.CreateNode("element", "messagename", ""); this.Header.AppendChild(node);
node = document.CreateNode("element", "transactionid", ""); this.Header.AppendChild(node);
node.InnerXml = Guid.NewGuid().ToString();
node = document.CreateNode("element", "sendSubjectName", ""); this.Header.AppendChild(node);
node = document.CreateNode("element", "replySubjectName", ""); this.Header.AppendChild(node);
this.Body = document.CreateNode("element", "body", "");
this.Message.AppendChild(this.Body);
node = document.CreateNode("element", "SITEID", ""); this.Body.AppendChild(node);
node = document.CreateNode("element", "EQUIPMENTID", ""); this.Body.AppendChild(node);
node = document.CreateNode("element", "DATETIME", ""); this.Body.AppendChild(node);
node.InnerXml = System.DateTime.Now.ToString("yyyyMMddHHmmss");
node = document.CreateNode("element", "CONTROLMODE", ""); this.Body.AppendChild(node);
}
public XmlData(string xmlData)
{
this.FromString(xmlData);
}
public override string ToString()
{
return $"{this.MessageName} - {this.TransactionID}";
}
#endregion
#region [ Public Method ] =============================================
#endregion
#region [ Method ] ====================================================
/// <summary>
/// FromString
/// </summary>
/// <param name="xmlData"></param>
public void FromString(string xmlData)
{
XmlDocument document = new XmlDocument();
this.Document = document;
if (string.IsNullOrEmpty(xmlData)) return;
document.LoadXml(xmlData.XMLUnescape());
this.Message = document.GetSingleNodeByName("Message");
this.Header = document.GetSingleNodeByName("Header");
this.Body = document.GetSingleNodeByName("Body");
XmlNode msgName = this.Header.GetSingleNodeByName("MessageName");
if (msgName.GetText().ToUpper().EndsWith("REQUEST")) this.SendRequestFlag = true;
else this.SendRequestFlag = false;
// SendRequest 파일에 정의된 속성값을 읽고, 메모리에서는 제거한다.
XmlNode msgNode = this.Document.GetSingleNodeByName("Message");
XmlAttribute attSendRequestFlag = msgNode.GetAttribute("SendRequestFlag");
if (attSendRequestFlag != null)
{
bool isSendRequestFlag = this.SendRequestFlag;
if (bool.TryParse(attSendRequestFlag.Value, out isSendRequestFlag)) this.SendRequestFlag = isSendRequestFlag;
msgNode.Attributes.Remove(attSendRequestFlag);
}
}
#endregion
#region [ Public Method ] =============================================
public string GetText()
{
return this.Document?.GetBeautify(4, false);
}
/// <summary>
/// 지정된 노드의 값을 반환한다
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetValue(string name)
{
if (this.Document == null) return string.Empty;
return this.Document.GetSingleNodeByName(name)?.InnerXml;
}
/// <summary>
/// 지정된 노드의 값을 변경한다
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public XmlNode SetValue(string name, string value)
{
XmlNode node = this.GetNode(name);
if (node == null) return null;
node.InnerXml = value;
return node;
}
/// <summary>
/// 지정된 노드를 반환한다
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public XmlNode GetNode(string name)
{
if (this.Document == null) return null;
XmlNode node = this.Document.GetSingleNodeByName(name);
return node;
}
/// <summary>
/// 지정된 노드들을 반환한다
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public XmlNode[] GetNodes(string name)
{
if (this.Document == null) return null;
XmlNode[] nodes = this.Document.GetNodesByName(name);
return nodes;
}
/// <summary>
/// 참조된 노드의 하위에 노드를 추가한다
/// </summary>
/// <param name="node"></param>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public XmlNode AddChildNode(XmlNode node, string name, string value = "")
{
XmlNode newNode = this.Document.CreateNode("element", name, "");
if (!string.IsNullOrEmpty(value)) newNode.InnerXml = value;
node.AppendChild(newNode);
return newNode;
}
/// <summary>
/// 참조된 노드의 앞에 노드를 추가한다
/// </summary>
/// <param name="node"></param>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public XmlNode InsertBefore(XmlNode node, string name, string value = "")
{
XmlNode newNode = this.Document.CreateNode("element", name, "");
if (!string.IsNullOrEmpty(value)) newNode.InnerXml = value;
this.Document.InsertBefore(newNode, node);
return newNode;
}
/// <summary>
/// 참조된 노드의 뒤에 노드를 추가한다
/// </summary>
/// <param name="node"></param>
/// <param name="name"></param>
/// <param name="value"></param>
/// <returns></returns>
public XmlNode InsertAfter(XmlNode node, string name, string value = "")
{
XmlNode newNode = this.Document.CreateNode("element", name, "");
if (!string.IsNullOrEmpty(value)) newNode.InnerXml = value;
this.Document.InsertAfter(newNode, node);
return newNode;
}
/// <summary>
/// return 노드를 반환한다
/// </summary>
/// <returns></returns>
public XmlNode GetReturn()
{
XmlNode node = this.GetNode("return");
if (node != null) return node;
return InsertAfter(this.Body, "return");
}
#endregion
}
}

255
JWH/TIB/XmlMessage.cs Normal file
View File

@@ -0,0 +1,255 @@
using System;
using System.Collections.Generic;
using System.Threading;
using JWH;
using TIBCO.Rendezvous;
namespace JWH.TIB
{
/// <summary>
/// TIBCO.Message & XmlData를 관리
/// </summary>
public class XmlMessage : IDisposable
{
#region [ Event ] =====================================================
public event EventHandler OnTimeOver;
#endregion
#region [ Variable ] ==================================================
public Timer SendReplyTimer { get; protected set; } = null;
private Message m_Message = null;
#endregion
#region [ Properties ] ================================================
/// <summary>
/// 수신된 RequestMessage
/// </summary>
public XmlMessage RequestMessage { get; set; } = null;
/// <summary>
/// TIBCO.Message
/// </summary>
public Message Message { get { return GetMessage(); } }
/// <summary>
/// SendRequestFlag
/// </summary>
public bool SendRequestFlag { get; set; } = false;
/// <summary>
/// IsReply
/// </summary>
public bool IsReply { get; set; } = false;
/// <summary>
/// XmlData
/// </summary>
public XmlData XmlData { get; set; } = null;
/// <summary>
/// TIBCO.Message.SendSubject (!=XmlData.SendSubjectName)
/// </summary>
public string SendSubject { get; set; } = string.Empty;
/// <summary>
/// TIBCO.Message.ReplySubject (!=XmlData.ReplySubjectName)
/// </summary>
public string ReplySubject { get; set; } = string.Empty;
/// <summary>
/// TIBCO.Rendezvous.Message.Fields
/// </summary>
public Dictionary<string, object> Fields { get; set; } = new Dictionary<string, object>();
#endregion
#region [ Constructor ] ===============================================
/// <summary>
/// XmlMessage
/// </summary>
public XmlMessage()
{
this.XmlData = new XmlData();
}
/// <summary>
/// 메시지 파일을 기준으로 생성
/// </summary>
/// <param name="xmlData"></param>
public XmlMessage(string xmlData)
{
this.XmlData = new XmlData(xmlData);
this.SendRequestFlag = this.XmlData.SendRequestFlag;
}
/// <summary>
/// TIBCO.Message 정보를 기준으로 생성
/// </summary>
/// <param name="message"></param>
public XmlMessage(Message message)
{
this.m_Message = message;
for (uint i = 0; i < message.FieldCount; i++)
{
MessageField field = message.GetFieldByIndex(i);
switch (field.Name.ToUpper())
{
case "XMLDATA":
if (field.Value != null && field.Value.GetType() == typeof(string)) this.XmlData = new XmlData(field.Value.ToString());
break;
case "SENDREQUESTFLAG":
if (field.Value != null && field.Value.GetType() == typeof(bool)) this.SendRequestFlag = (bool)Convert.ChangeType(field.Value, typeof(bool));
break;
default:
this.Fields.Add(field.Name, field.Value);
break;
}
}
this.SendSubject = message.SendSubject;
this.ReplySubject = message.ReplySubject;
}
~XmlMessage()
{
XLogger.Instance.Debug($"{this.XmlData?.MessageName} {this.XmlData?.TransactionID}");
this.Dispose();
}
public void Dispose()
{
try
{
if (this.SendReplyTimer != null)
{
this.SendReplyTimer.Dispose();
this.SendReplyTimer = null;
}
if (this.RequestMessage != null)
{
this.RequestMessage.Dispose();
this.RequestMessage = null;
}
if (this.m_Message != null)
{
XLogger.Instance.Debug($"{m_Message}");
this.m_Message.Dispose();
this.m_Message = null;
}
}
catch (Exception ex)
{
XLogger.Instance.Fatal(ex);
}
}
public override string ToString()
{
return $"{this.XmlData?.ToString()}";
}
#endregion
#region [ Raise_Events ] ==============================================
private void Raise_OnTimeOut()
{
this.OnTimeOver?.Invoke(this, new EventArgs());
}
#endregion
#region [ Public Method ] =============================================
public void SetRequstMessage(XmlMessage xmlRequest)
{
this.RequestMessage = xmlRequest;
this.IsReply = true;
this.SendSubject = xmlRequest.XmlData.ReplySubjectName;
this.ReplySubject = xmlRequest.ReplySubject;
//if (!string.IsNullOrEmpty(xmlRequest.ReplySubject)) this.SendSubject = xmlRequest.ReplySubject;
this.XmlData.TransactionID = xmlRequest.XmlData.TransactionID;
this.XmlData.SendSubjectName = xmlRequest.XmlData.ReplySubjectName;
this.XmlData.ReplySubjectName = xmlRequest.XmlData.SendSubjectName;
}
/// <summary>
/// SendReply Timeout 체크를 시작한다
/// </summary>
/// <param name="interval"></param>
public void TimerStart(int interval = 30)
{
interval = interval * 1000;
this.SendReplyTimer = new Timer(this.SendReplyTimer_TimeOut, null, interval, Timeout.Infinite);
}
/// <summary>
/// SendReply Timeout 체크를 중지한다
/// </summary>
public void TimerStop()
{
if (this.SendReplyTimer != null)
{
this.SendReplyTimer.Dispose();
this.SendReplyTimer = null;
}
}
/// <summary>
/// SendReply Timeout
/// </summary>
/// <param name="state"></param>
private void SendReplyTimer_TimeOut(object state)
{
this.SendReplyTimer.Dispose();
this.SendReplyTimer = null;
this.Raise_OnTimeOut();
}
#endregion
#region [ Method ] ====================================================
/// <summary>
/// 현 객체의 정보를 TIBCO.Message로 반환한다
/// </summary>
/// <returns></returns>
private Message GetMessage()
{
try
{
if (this.m_Message != null) return this.m_Message;
Message message = new Message();
if (!string.IsNullOrEmpty(this.SendSubject)) message.SendSubject = this.SendSubject;
if (!string.IsNullOrEmpty(this.ReplySubject)) message.ReplySubject = this.ReplySubject;
message.AddField("xmlData", this.XmlData.GetText());
message.AddField("SendRequestFlag", this.SendRequestFlag);
return message;
}
catch (Exception ex)
{
throw ex;
}
}
#endregion
}
}