/// <summary> /// Instantiates MmfWriter. /// </summary> /// <param name="ipcType">Identifies memory mapped file and used to authenticate outgoing messages.</param> /// <param name="bufferLength">Length of data segment</param> /// <param name="ignoreExceptions">True if exceptions should be handled; false if they should be returned to the caller.</param> public MmfWriter(string ipcType, int bufferLength, Niawa.Utilities.UtilsServiceBus utilsBus, bool ignoreExceptions) { try { _sendQueue = new Queue<NiawaMmfContainer>(); _ipcType = ipcType; _description = "MmfWriter " + _ipcType; _bufferLength = bufferLength; _ignoreExceptions = ignoreExceptions; //initialize serial ID generator id = utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_MMF_CONTAINER); //get random starting message ID Random rnd = new Random(); int startingMsgID = rnd.Next(0, 100000); _msgID = startingMsgID; _threadStatus = new Niawa.Threading.ThreadStatus(_description, 60, utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_THREAD_ID).ToString(), string.Empty, null); //thread status _threadStatus.Status = Niawa.Threading.ThreadStatus.STATUS_INITIALIZED; } catch (Exception ex) { logger.Error("[" + _description + "-M] Exception while instantiating: " + ex.Message, ex); if (!ignoreExceptions) throw ex; } }
/// <summary> /// Instantiates IpcEventWriter by initializing MmfWriter. /// </summary> /// <param name="applicationName">Application name to use in MmfWriter</param> /// <param name="ipcType">Identifies and authenticates data for memory mapped file</param> /// <param name="ipcEventMessageLength">Length of data segment</param> /// <param name="ignoreIpcExceptions">True if write exceptions in MmfWriter should be handled by MmfWriter; false if they should be returned.</param> public IpcEventWriter(string applicationName, string ipcType, int ipcEventMessageLength, Niawa.Utilities.UtilsServiceBus utilsBus, bool ignoreIpcExceptions) { try { _applicationName = applicationName; _ipcType = ipcType; _ipcEventMessageLength = ipcEventMessageLength; _ignoreIpcExceptions = ignoreIpcExceptions; //initialize serial ID generator id = utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_IPC_EVENT); //initialize MMF writer mmfWriter = new Niawa.IpcController.MmfBufferedWriter(_ipcType, _ipcEventMessageLength, utilsBus, _ignoreIpcExceptions); lockSection = new System.Threading.Semaphore(1, 1); } catch (Exception ex) { logger.Error("[IpcEventWriter " + _ipcType + "] Caught exception during IpcEventWriter instantiate: " + ex.Message, ex); if (ignoreIpcExceptions) { } else throw ex; } }
public void Setup() { int serialIDRoot = 123; int serialIDSession = 456; int serialIDSerial = 789; _testSerialID = new Utilities.SerialId(serialIDRoot, serialIDSession, serialIDSerial); //create mock event raiser _evtRaiser = new MockedObjects.MockedEventRaiser("TestAppGroup", "TestAppName", "TestAppInstance", null); //create thread status _threadStatus = new Threading.ThreadStatus("TestThreadStatus", 60, _testSerialID.ToString(), string.Empty, _evtRaiser); }
/// <summary> /// Event Raiser contains the mechanism to raise events. Event consumers are added (subscribed) and removed (unsubscibed), and when an event /// is raised the consumers will receive the event and add to the queue to be handled by their implementor. /// </summary> /// <param name="applicationGroup"></param> /// <param name="applicationName"></param> /// <param name="applicationInstance"></param> /// <param name="utilsBus"></param> public EventRaiser(string applicationGroup, string applicationName, string applicationInstance, Niawa.Utilities.UtilsServiceBus utilsBus) { try { _applicationGroup = applicationGroup; _applicationName = applicationName; _applicationInstance = applicationInstance; //initialize serial ID generator id = utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_EVENT_MESSAGE); } catch (Exception ex) { logger.Error("[EventRaiser] Error while instantiating: " + ex.Message, ex); } }
/// <summary> /// Instantiates UdpTransmitter. /// </summary> /// <param name="port">Port to transmit UDP messages on.</param> /// <param name="evtConsumer">Consumer for events raised by Niawa.MsEventController.EventRaiser</param> public UdpTransmitter(int port, Niawa.MsEventController.EventConsumer evtConsumer, Niawa.Utilities.UtilsServiceBus utilsBus, string applicationNameDetailed, string parentNodeID) { try { _applicationNameDetailed = applicationNameDetailed; _port = port; _sendQueue = new Queue<NiawaNetDatagram>(); _sentMessageGuidBuffer = new List<Guid>(); lockSection = new System.Threading.Semaphore(1, 1); lockSentMessageGuidBuffer = new System.Threading.Semaphore(1, 1); _description = "UdpTransmitter " + _port.ToString(); _evtConsumer = evtConsumer; //initialize the endpoints _groupEndpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Broadcast, _port); //_localEP = new System.Net.IPEndPoint(System.Net.IPAddress.Loopback, _port); //initialize serial ID generator id = utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_NET_DATAGRAM); //initialize event logging _evtRaiser = new MsEventController.EventRaiser("UdpTransmitter", _applicationNameDetailed, _description, utilsBus); if (_evtConsumer != null) _evtRaiser.AddEventConsumer(_evtConsumer); _threadStatus = new Niawa.Threading.ThreadStatus(_description, 60, utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_THREAD_ID).ToString(), parentNodeID, _evtRaiser); //thread status _threadStatus.Status = Niawa.Threading.ThreadStatus.STATUS_INITIALIZED; //add thread elective properties. _threadStatus.AddElectiveProperty("Port", _port.ToString()); } catch (Exception ex) { logger.Error("[UdpTransmitter-M] Error while instantiating: " + ex.Message, ex); throw ex; } }
/// <summary> /// Instantiates TcpTransmitter /// </summary> /// <param name="ipAddress">IP Address to transmit TCP messages on</param> /// <param name="port">Network port to transmit TCP messages on</param> /// <param name="evtConsumer">Consumer for events raised by Niawa.MsEventController.EventRaiser</param> public TcpTransmitter(string ipAddress, int port, Niawa.MsEventController.EventConsumer evtConsumer, Niawa.Utilities.UtilsServiceBus utilsBus, string applicationNameDetailed, string parentNodeID) { try { _applicationNameDetailed = applicationNameDetailed; _ipAddress = ipAddress; _port = port; _evtConsumer = evtConsumer; lockSection = new System.Threading.Semaphore(1, 1); _description = "TcpTransmitter " + _ipAddress + ":" + _port.ToString(); _sendQueue = new Queue<NiawaNetMessage>(); //initialize serial ID generator id = utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_NET_MESSAGE); //initialize event logging _evtRaiser = new MsEventController.EventRaiser("TcpTransmitter", _applicationNameDetailed, _description, utilsBus); //_evtRaiserMsg = new MsEventController.EventRaiser("TcpTransmitterMsg", _applicationNameDetailed, _description, utilsBus); if (_evtConsumer != null) _evtRaiser.AddEventConsumer(_evtConsumer); //if (_evtConsumer != null) _evtRaiserMsg.AddEventConsumer(_evtConsumer); _threadStatus = new Niawa.Threading.ThreadStatus(_description, 60, utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_THREAD_ID).ToString(), parentNodeID, _evtRaiser); //thread status _threadStatus.Status = Niawa.Threading.ThreadStatus.STATUS_INITIALIZED; //add thread elective properties. _threadStatus.AddElectiveProperty("IpAddress", _ipAddress); _threadStatus.AddElectiveProperty("Port", _port.ToString()); } catch (Exception ex) { logger.Error("[TcpTransmitter-M] Error instantiating: " + ex.Message, ex); throw ex; } }
//string messageDetail) /// <summary> /// Raise a new event. Any event consumrs that are added (subscribed) will receive the event, and add to their queue to be handled by their impelementor. /// </summary> /// <param name="messageType"></param> /// <param name="message"></param> /// <param name="messageDetail"></param> /// <param name="nodeID"></param> /// <param name="parentNodeID"></param> public void RaiseEvent(string messageType, string message, SortedList<string, string> messageDetail, string nodeID, string parentNodeID) { try { //if(messageDetail == null) messageDetail = new SortedList<string, string>(); ////add thread ID to message detail //if (messageDetail.ContainsKey("ThreadID")) messageDetail.Remove("ThreadID"); //if (messageDetail.ContainsKey("ParentThreadID")) messageDetail.Remove("ParentThreadID"); //messageDetail.Add("ThreadID", threadID); //messageDetail.Add("ParentThreadID", parentThreadID); //serialize message detail string messageDetailSerialized = Newtonsoft.Json.JsonConvert.SerializeObject(messageDetail); //get next serial ID id = Niawa.Utilities.IdGeneratorUtils.IncrementSerialId(id); //create event NiawaEventMessageArgs ea = new NiawaEventMessageArgs(_applicationGroup, _applicationName, _applicationInstance, messageType, message, messageDetailSerialized, nodeID, parentNodeID, id.ToString()); logger.Debug("[EventRaiser " + _applicationGroup + " " + _applicationInstance + "] Raising event " + ea.SerialID); //raise event if (NiawaEventMessage != null) NiawaEventMessage(this, ea); } catch (Exception ex) { logger.Error("[EventRaiser] Error while raising event: " + ex.Message, ex); } }
/// <summary> /// Write a message to the MmfWriter. Message is queued and sent in a thread loop. /// </summary> /// <param name="message">Message to write</param> public void WriteData(NiawaMmfContainer message) { try { if (!_threadStatus.IsThreadEnabled || !_threadStatus.IsThreadActive) { throw new Exception("Cannot write data - writer is not active"); }; //get next serial ID id = Niawa.Utilities.IdGeneratorUtils.IncrementSerialId(id); message.SerialID = id.ToString(); logger.Debug("[" + _description + "-M] Writing data: " + message.SerialID); _sendQueue.Enqueue(message); } catch (Exception ex) { logger.Error("[" + _description + "-M] Exception while writing data: " + ex.Message, ex); if (!_ignoreExceptions) throw ex; } }
//public UdpTransmitter(int port, Niawa.MsEventController.EventConsumer evtConsumer, Niawa.Utilities.UtilsServiceBus utilsBus, string applicationNameDetailed, Niawa.Utilities.SerialId parentThreadId) //{ // try // { // _applicationNameDetailed = applicationNameDetailed; // _port = port; // _evtConsumer = evtConsumer; // _sendQueue = new Queue<NiawaNetDatagram>(); // lockSection = new System.Threading.Semaphore(1, 1); // _description = "UdpTransmitter " + _port.ToString(); // //initialize the endpoints // _groupEndpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Broadcast, _port); // _localEP = new System.Net.IPEndPoint(System.Net.IPAddress.Loopback, _port); // //initialize serial ID generator // id = utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_NET_DATAGRAM); // //initialize event logging // _evtRaiser = new MsEventController.EventRaiser("UdpTransmitter", _applicationNameDetailed, _description, utilsBus); // if (_evtConsumer != null) _evtRaiser.AddEventConsumer(_evtConsumer); // _threadStatus = new Niawa.Threading.ThreadStatus(_description, 60, utilsBus.InitializeSerialId(Niawa.Utilities.IdGeneratorUtils.ID_ROOT_NIAWA_THREAD_ID), parentThreadId, _evtRaiser); // //thread status // _threadStatus.Status = Niawa.Threading.ThreadStatus.STATUS_INITIALIZED; // //add thread elective properties. // _threadStatus.AddElectiveProperty("Port", _port.ToString()); // } // catch (Exception ex) // { // logger.Error("[UdpTransmitter-M] Error while instantiating: " + ex.Message, ex); // throw ex; // } //} /// <summary> /// Send UDP message. /// </summary> /// <param name="message">Message to send via UDP.</param> public void SendMessage(NiawaNetDatagram message) { try { if (!_threadStatus.IsThreadEnabled || !_threadStatus.IsThreadActive) { _evtRaiser.RaiseEvent("MessageError", "Cannot send message - Transmitter is not active" , Niawa.Utilities.InlineSortedListCreator.CreateStrStr("NiawaNetMessage", message.ToJson()) , _threadStatus.NodeID , _threadStatus.ParentNodeID); throw new MessageNotSentException("Cannot send message - transmitter is not active"); } //get next serial ID id = Niawa.Utilities.IdGeneratorUtils.IncrementSerialId(id); message.SerialID = id.ToString(); logger.Info("[" + _description + "-M] Queueing message: Type [" + message.MessageType + "] SerialID [" + message.SerialID + "]"); _sendQueue.Enqueue(message); } catch (Exception ex) { logger.Error("[" + _description + "-M] Error while sending message: " + ex.Message, ex); throw ex; } }
/// <summary> /// Send TCP message synchonously. Wait for message to send before returning. /// </summary> /// <param name="message"></param> public void SendMessageSynchronous(NiawaNetMessage message, int timeoutMs) { try { DateTime now = DateTime.Now; DateTime timeoutBy1 = now.AddMilliseconds(timeoutMs / 2); DateTime timeoutBy2 = now.AddMilliseconds(timeoutMs); //wait up to timeout seconds / 2 for transmitter to start int i1 = 0; while (!_threadStatus.IsThreadEnabled && !_threadStatus.IsThreadActive && timeoutBy1 < DateTime.Now) { i1++; System.Threading.Thread.Sleep(10); } if (timeoutBy1 < DateTime.Now) logger.Warn("[" + _description + "-M] Timed out waiting for transmitter to start while sending message synchronously"); System.Threading.Thread.Sleep(100); /****************/ /* send message */ //get next serial ID id = Niawa.Utilities.IdGeneratorUtils.IncrementSerialId(id); message.SerialID = id.ToString(); logger.Info("[" + _description + "-M] Queueing message: Type [" + message.MessageType + "] SerialID [" + message.SerialID + "]"); _sendQueue.Enqueue(message); /* send message */ /****************/ System.Threading.Thread.Sleep(100); //wait up to timeout seconds for message to send int i = 0; while (CountMessagesInBuffer() > 0 && timeoutBy2 < DateTime.Now) { i++; System.Threading.Thread.Sleep(10); } if (timeoutBy2 < DateTime.Now) logger.Warn("[" + _description + "-M] Timed out waiting for message to send while sending message synchronously"); } catch (Exception ex) { logger.Error("[" + _description + "-M] Error sending message synchronously: " + ex.Message, ex); throw ex; } }
/// <summary> /// Writes an event by enqueueing in MmfWriter. /// </summary> /// <param name="ipcEvent">IpcEvent message to write</param> public void Write(IpcEvent ipcEvent) { try { //attempt lock bool tryLock = lockSection.WaitOne(60000); if (!tryLock) throw new TimeoutException("[IpcEventWriter " + _ipcType + "] Could not obtain lock while writing event"); try { if (!started) throw new Exception("[IpcEventWriter " + _ipcType + "] Cannot write event " + ipcEvent.SerialID + ": IpcEventWriter is not started."); //get next serial ID id = Niawa.Utilities.IdGeneratorUtils.IncrementSerialId(id); ipcEvent.SerialID = id.ToString(); //create MMF message Niawa.IpcController.NiawaMmfContainer msg = new Niawa.IpcController.NiawaMmfContainer(System.DateTime.Now, _ipcType, ipcEvent.ToJson()); //, ipcEvent.EventID.ToString()); logger.Debug("[IpcEventWriter " + _ipcType + "] Writing IPC Event " + ipcEvent.SerialID + ""); //write MMF message mmfWriter.WriteData(msg); } finally { //release lock lockSection.Release(); } } catch (Exception ex) { logger.Error("[IpcEventWriter " + _ipcType + "] Caught exception during IpcEventWriter Write [" + ipcEvent.SerialID + "]: " + ex.Message, ex); if (_ignoreIpcExceptions) { } else throw ex; } }