/// <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; } }
/// <summary> /// Loop thread that reads the memory mapped file and adds items to the read queue. /// </summary> /// <param name="data"></param> private void ListenThreadImpl(object data) { try { _threadStatus.IsThreadActive = true; logger.Info("[" + _description + "-T] Reader active"); try { while (_threadStatus.IsThreadEnabled == true) { _threadStatus.ThreadHealthDate = DateTime.Now; DateTime duplicateErrorDate = DateTime.MinValue; //listening try { /* Memory Mapped File: * accessor1Len: bytes 0-4 total length of file * accessor2ID: bytes 8-12 ID number of message * accessor3Data: variable bytes payload * */ int msgLength; int msgID; //open mmf mmf = MemoryMappedFile.OpenExisting(_ipcType); MemoryMappedViewAccessor accessor1Len = mmf.CreateViewAccessor(0, 4); MemoryMappedViewAccessor accessor2ID = mmf.CreateViewAccessor(8, 4); MemoryMappedViewAccessor accessor3Data; //locked section using (new Niawa.Utilities.SingleGlobalInstance(1000, _ipcType)) //1000ms timeout on global lock { //get length, ID, and data msgLength = accessor1Len.ReadInt32(0); msgID = accessor2ID.ReadInt32(0); accessor3Data = mmf.CreateViewAccessor(16, msgLength); } System.Diagnostics.Debug.WriteLine("MmfReader: MsgID: " + msgID); System.Diagnostics.Debug.WriteLine("MmfReader: LastMsgID: " + _lastMsgID); //check if ID changed if (msgID == _lastMsgID) { System.Diagnostics.Debug.WriteLine("MmfReader: There is no work to do"); //do nothing System.Threading.Thread.Sleep(10); } else { System.Diagnostics.Debug.WriteLine("MmfReader: Reading message"); //set ID _lastMsgID = msgID; //check if message is too long if (msgLength + 16 > _bufferLength) { logger.Error("[" + _description + "-T] Not reading message [" + msgID + "]: Message length [" + (msgLength + 16).ToString() + "] is greater than the buffer length [" + _bufferLength.ToString() + "]"); _threadStatus.MessageErrorCount += 1; } else { //get data byte[] buffer = new byte[msgLength]; accessor3Data.ReadArray<byte>(0, buffer, 0, msgLength); NiawaMmfContainer msg = new NiawaMmfContainer(buffer); logger.Debug("[" + _description + "-T] Received data [" + msgID + "]: " + msg.SerialID); _threadStatus.MessageCount += 1; _receiveQueue.Enqueue(msg); } } } catch (System.IO.FileNotFoundException) { //file does not exist System.Diagnostics.Debug.WriteLine("MmfReader [" + _ipcType + "]: File was not found"); //log message every 10 seconds TimeSpan ts = DateTime.Now - duplicateErrorDate; if (ts.TotalSeconds > 10) { duplicateErrorDate = DateTime.Now; logger.Debug("[" + _description + "-T] Mmf not initiated by provider"); } //sleep for 250 ms System.Threading.Thread.Sleep(250); } catch (System.Threading.ThreadAbortException) // ex1) { //thread was aborted; re-enter loop logger.Info("[" + _description + "-T] Thread aborted"); break; } catch (System.Threading.ThreadInterruptedException) // ex1) { //thread was interrupted; re-enter loop logger.Info("[" + _description + "-T] Thread interrupted"); break; } catch (Exception ex) { //exception logger.Error("[" + _description + "-T] Exception while listening for next message: " + ex.Message, ex); _threadStatus.ErrorCount += 1; System.Threading.Thread.Sleep(100); } System.Threading.Thread.Sleep(50); } //done listening } finally { _threadStatus.IsThreadActive = false; _threadStatus.IsThreadEnabled = false; logger.Info("[" + _description + "-T] Reader inactive"); } } catch (Exception ex) { logger.Error("[" + _description + "-T] Exception in listen thread: " + ex.Message, ex); if (!_ignoreExceptions) throw ex; } }
/// <summary> /// Reads data from Mmf file and inserts into read queue /// </summary> private void ReadFromMmfFile(int entryID) { /* Memory Mapped File: * accessor1Len: bytes 0-4 total length of file * accessor2ID: bytes 8-12 ID number of message * accessor3Data: variable bytes payload * */ int msgLength; int msgID; try { //System.Diagnostics.Debug.WriteLine("MmfBufferedReader [File " + entryID + "]: Filename " + _ipcType + "_" + entryID); //open mmf MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(_ipcType + "_" + entryID); MemoryMappedViewAccessor accessor1Len = mmf.CreateViewAccessor(0, 4); MemoryMappedViewAccessor accessor2ID = mmf.CreateViewAccessor(8, 4); MemoryMappedViewAccessor accessor3Data; //locked section using (new Niawa.Utilities.SingleGlobalInstance(1000, _ipcType)) //1000ms timeout on global lock { //get length, ID, and data msgLength = accessor1Len.ReadInt32(0); msgID = accessor2ID.ReadInt32(0); accessor3Data = mmf.CreateViewAccessor(16, msgLength); } //System.Diagnostics.Debug.WriteLine("MmfBufferedReader [File " + entryID + "]: MsgID: " + msgID); //System.Diagnostics.Debug.WriteLine("MmfBufferedReader [File " + entryID + "]: LastMsgID: " + _lastMsgID); //check if ID changed if (msgID == _lastMsgID) { //System.Diagnostics.Debug.WriteLine("MmfBufferedReader [File " + entryID + "]: There is no work to do"); //do nothing System.Threading.Thread.Sleep(10); } else { //System.Diagnostics.Debug.WriteLine("MmfBufferedReader [File " + entryID + "]: Reading message"); //set ID _lastMsgID = msgID; //check if message is too long if (msgLength + 16 > _bufferLength) { logger.Error("[" + _description + "-T] Not reading message [" + msgID + "]: Message length [" + (msgLength + 16).ToString() + "] is greater than the buffer length [" + _bufferLength.ToString() + "]"); _threadStatus.MessageErrorCount += 1; } else { //get data byte[] buffer = new byte[msgLength]; accessor3Data.ReadArray<byte>(0, buffer, 0, msgLength); NiawaMmfContainer msg = new NiawaMmfContainer(buffer); logger.Debug("[" + _description + "-T] Received data [" + msgID + "]: " + msg.SerialID); _threadStatus.MessageCount += 1; _receiveQueue.Enqueue(msg); } } } catch (System.IO.FileNotFoundException) { System.Diagnostics.Debug.WriteLine("MmfBufferedReader [" + _ipcType + "][File " + entryID + "]: File was not found"); } }