public void SendToChannel(string channelName, string message) { if (string.IsNullOrEmpty(channelName)) { throw new ArgumentNullException(channelName, "The channel name must be defined"); } if (message == null) { throw new ArgumentNullException(message, "The messsage packet cannot be null"); } if (string.IsNullOrEmpty(channelName)) { throw new ArgumentException("The channel name may not contain the ':' character.", "channelName"); } // create a DataGram instance, and ensure memory is freed using (DataGram dataGram = new DataGram(channelName, message)) { // Allocate the DataGram to a memory address contained in COPYDATASTRUCT Native.COPYDATASTRUCT dataStruct = dataGram.ToStruct(); // Use a filter with the EnumWindows class to get a list of windows containing // a property name that matches the destination channel. These are the listening // applications. WindowEnumFilter filter = new WindowEnumFilter(XDListener.GetChannelKey(channelName)); WindowsEnum winEnum = new WindowsEnum(filter.WindowFilterHandler); foreach (IntPtr hWnd in winEnum.Enumerate()) { IntPtr outPtr = IntPtr.Zero; // For each listening window, send the message data. Return if hang or unresponsive within 1 sec. Native.SendMessageTimeout(hWnd, Native.WM_COPYDATA, IntPtr.Zero, ref dataStruct, Native.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out outPtr); } } }
public static CommDatagram ParseDatagram(DataGram datagram) { CommDatagram result = new CommDatagram(); int idx = -1; //Sender ID string msgPart = GetMessagePart(datagram.Message, ref idx); if (msgPart == null) { return(null); } result.SenderId = new Guid(msgPart); //Message type msgPart = GetMessagePart(datagram.Message, ref idx); if (msgPart == null) { return(null); } result.MessageType = (MessageType)Convert.ToInt32(msgPart); //Data msgPart = datagram.Message.Substring(idx + 1, datagram.Message.Length - idx - 1); result.Data = msgPart; return(result); }
/// <summary> /// Handles messages received from other machines on the network and dispatches them locally. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnMessageReceived(object sender, XDMessageEventArgs e) { // network message is of format machine:channel:message if (e.DataGram.IsValid) { using (DataGram machineInfo = DataGram.ExpandFromRaw(e.DataGram.Message)) { if (machineInfo.IsValid) { // don't relay if the message was broadcast on this machine if (machineInfo.Channel != Environment.MachineName) { using (DataGram dataGram = DataGram.ExpandFromRaw(machineInfo.Message)) { if (dataGram.IsValid) { // propagate the message on this machine using the same mode as the sender nativeBroadcast.SendToChannel(dataGram.Channel, dataGram.Message); } } } } } } }
/// <summary> /// This method processes the message and triggers the MessageReceived event. /// </summary> /// <param name="dataGram"></param> private void OnMessageReceived(DataGram dataGram) { if (MessageReceived != null) { // trigger this async MessageReceived.Invoke(this, new XDMessageEventArgs(dataGram)); } }
/// <summary> /// Constructor which creates the data gram from a message and channel name. /// </summary> /// <param name = "serializer"></param> /// <param name = "channel">The channel through which the message will be sent.</param> /// <param name = "dataType">The type of the message used for deserialization hints.</param> /// <param name = "message">The string message to send.</param> internal WinMsgDataGram(ISerializer serializer, string channel, string dataType, string message) { Validate.That(serializer).IsNotNull(); this.serializer = serializer; allocatedMemory = false; dataStruct = new Native.COPYDATASTRUCT(); dataGram = new DataGram(channel, dataType, message); }
void OnNewData(object sender, DataGram dg) { Worker.Enqueue("Cluster OnNewData", () => { try { if (dg.Data[0] == '{') { // Debug.WriteLine("Llega un JSON..."); } else { using (var ms = new MemoryStream(dg.Data)) { BinaryFormatter bf = new BinaryFormatter(); object msg = bf.Deserialize(ms); if (msg is MsgType type) { switch (type) { case MsgType.Activate: //Debug.WriteLine("Activate(true)"); break; case MsgType.Deactivate: //Debug.WriteLine("Deactivate()"); break; case MsgType.GetState: //Debug.WriteLine("SendState()"); break; default: //Debug.WriteLine("Error 1"); break; } } else if (msg is NodeInfo) { //Debug.WriteLine("NodeInfo..."); } else { throw new Exception("Mensaje Desconocido"); } } } } catch (Exception ex) { //Debug.WriteLine($"Excepcion: {ex.Message}"); } }); }
private void SendToChannel(string channel, string dataType, string message) { channel.Requires("channel").IsNotNull(); dataType.Requires("dataType").IsNotNull(); message.Requires("message").IsNotNullOrWhiteSpace(); var topic = topicRepository.GetTopic(channel); var dataGram = new DataGram(channel, dataType, message); var data = serializer.Serialize(dataGram); publisherService.Publish(topic, dataGram.Channel, data); }
private void SendToChannel(string channel, string dataType, string message) { Validate.That(channel).IsNotNull(); Validate.That(dataType).IsNotNull(); Validate.That(message).IsNotNullOrEmpty(); var topic = topicRepository.GetTopic(channel); var dataGram = new DataGram(channel, dataType, message); var data = serializer.Serialize(dataGram); publisherService.Publish(topic, dataGram.Channel, data); }
private void ProcessMessage(object state) { string filepath = state as string; try { // check if file exists if (File.Exists(filepath)) { string rawmessage = null; // try to load the file in shared access mode using (FileStream stream = File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (StreamReader reader = new StreamReader(stream)) { rawmessage = reader.ReadToEnd(); } } using (DataGram dataGram = DataGram.ExpandFromRaw(rawmessage)) { if (dataGram.IsValid) { // dispatch the message received event MessageReceived(this, new XDMessageEventArgs(dataGram)); } } try { File.Delete(filepath); } catch { } } } catch (FileNotFoundException) { // if for any reason the file was deleted before the message could be read from the file, // then can safely ignore this message } catch (UnauthorizedAccessException ue) { throw new UnauthorizedAccessException(string.Format("Unable to bind to channel as access is denied." + " Ensure the process has read/write access to the directory '{0}'.", filepath), ue); } catch (IOException ie) { throw new IOException(string.Format("There was an unexpected IO error binding to a channel." + " Ensure the process is unable to read/write to directory '{0}'.", filepath), ie); } }
public void GivenADatagramWhenSerializedThenSuccess() { // arrange var dataGram = new DataGram(channel, assemblyQualifiedName, message); // act var result = serializer.Serialize(dataGram); // assert Assert.That(result, Does.Contain(channel)); Assert.That(result, Does.Contain(message)); Assert.That(result, Does.Contain(assemblyQualifiedName)); Assert.That(result, Does.Contain("1.1")); }
public byte[] Receive(ref IPv4.EndPoint source) { if (this.rxBuffer.Count < 1) { return(null); } DataGram packet = rxBuffer.Dequeue(); source.address = packet.source.address; source.port = packet.source.port; return(packet.data); }
public void GivenADatagramThenWhenSerializedAssertSuccess() { // arrange var dataGram = new DataGram(channel, assemblyQualifiedName, message); // act var result = serializer.Serialize(dataGram); // assert Assert.That(result, Is.StringContaining(channel)); Assert.That(result, Is.StringContaining(message)); Assert.That(result, Is.StringContaining(assemblyQualifiedName)); Assert.That(result, Is.StringContaining("1.1")); }
public void GivenADatagramWithSpecialCharsWhenSerializedThenSuccess() { // arrange var specialMsg = "汉字"; var dataGram = new DataGram(channel, assemblyQualifiedName, specialMsg); // act var result = serializer.Serialize(dataGram); // assert Assert.That(result, Does.Contain(channel)); Assert.That(result, Does.Contain(specialMsg)); Assert.That(result, Does.Contain(assemblyQualifiedName)); Assert.That(result, Does.Contain("1.1")); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="dg"></param> void OnNewData(object sender, DataGram dg) { try { MemoryStream ms = new MemoryStream(dg.Data); CustomBinaryFormatter bf = new CustomBinaryFormatter(); SactaMsg msg = bf.Deserialize <SactaMsg>(ms); if (IsValid(msg)) { int net = (sender == _Comm[0] ? 0 : 1); _LastScvReceived[net] = DateTime.Now; switch (msg.Type) { case SactaMsg.MsgType.Presence: _ActivityTimeOut = (uint)(((SactaMsg.PresenceInfo)(msg.Info)).ActivityTimeOutSg * 1000); if (_ActivityTimeOut < 5) { _ActivityTimeOut = Settings.Default.ActivityTimeOut; } break; case SactaMsg.MsgType.SectAsk: SendSectorization(net, _SectorUcs, msg.UserOrg); MainForm.LogMethod("INFO", net == 0 ? "SACTA1" : "SACTA2", "Recibida Peticion de Sectorizacion"); break; case SactaMsg.MsgType.SectAnwer: SactaMsg.SectAnswerInfo info = (SactaMsg.SectAnswerInfo)(msg.Info); MainForm.LogMethod("INFO", net == 0 ? "SACTA1" : "SACTA2", String.Format("Sectorizacion V-{0}: {1}", info.Version, (info.Result == 1 ? "Implantada" : "Rechazada"))); break; case SactaMsg.MsgType.Init: MainForm.LogMethod("INFO", net == 0 ? "SACTA1" : "SACTA2", "Recibido MSG INIT"); _SeqNum = 0; break; } } } catch (Exception ex) { if (!_Disposed) { MainForm.LogMethod("ERROR", "OnNewData", String.Format("Excepción al Procesar Datos Recibidos: {0}", ex.Message)); } } }
/// <summary> /// Extracts the message for the buffer and raises the MessageReceived event. /// </summary> /// <param name="buffer"></param> /// <param name="bytesRead"></param> private void ProcessMessage(byte[] buffer, uint bytesRead) { BinaryFormatter b = new BinaryFormatter(); string rawMessage = string.Empty; try { rawMessage = Encoding.UTF8.GetString(buffer, 0, (int)bytesRead); } catch { // if something goes wrong such as handle is closed, // we will not process this message } /* * using (MemoryStream stream = new MemoryStream()) * { * stream.Write(buffer, 0, (int)bytesRead); * stream.Flush(); * // reset the stream cursor back to the beginning * stream.Seek(0, SeekOrigin.Begin); * try * { * rawMessage = (string)b.Deserialize(stream); * } * catch (SerializationException) { } // if something goes wrong such as handle is closed, * // we will not process this message * }*/ // mailslot message format is id:channel:message using (DataGram dataGramId = DataGram.ExpandFromRaw(rawMessage)) { // only dispatch event if this is a new message // this filters out mailslot duplicates which are sent once per protocol if (dataGramId.IsValid && dataGramId.Channel != lastMessageId) { // remember we have seen this message lastMessageId = dataGramId.Channel; using (DataGram dataGram = DataGram.ExpandFromRaw(dataGramId.Message)) { if (dataGram.IsValid) { OnMessageReceived(dataGram); } } } } }
/// <summary> /// A helper method used to update the Windows Form. /// </summary> /// <param name="dataGram">dataGram</param> private void UpdateDisplayText(DataGram dataGram) { Color textColor; switch (dataGram.Channel.ToLower()) { case "status": textColor = Color.Green; break; default: textColor = Color.Blue; break; } string msg = string.Format("{0}: {1}\r\n", dataGram.Channel, dataGram.Message); UpdateDisplayText(msg, textColor); }
private void SendToChannel(string channelName, string dataType, string message) { channelName.Requires("channelName").IsNotNullOrWhiteSpace(); dataType.Requires("dataType").IsNotNullOrWhiteSpace(); message.Requires("message").IsNotNullOrWhiteSpace(); var fileName = Guid.NewGuid().ToString(); var folder = GetChannelDirectory(channelName); var filePath = Path.Combine(folder, string.Concat(fileName, ".msg")); using (var writer = File.CreateText(filePath)) { var dataGram = new DataGram(channelName, dataType, message); writer.Write(serializer.Serialize(dataGram)); writer.Flush(); } ThreadPool.QueueUserWorkItem(CleanUpMessages, new FileInfo(filePath).Directory); }
/// <summary> /// Constructor creates an instance of the class from a pointer address, and expands /// the data packet into the originating channel name and message. /// </summary> /// <param name = "lpParam">A pointer the a COPYDATASTRUCT containing information required to /// expand the DataGram.</param> /// <param name = "serializer">Serializer to deserialize raw DataGram message.</param> private WinMsgDataGram(IntPtr lpParam, ISerializer serializer) { Validate.That(serializer).IsNotNull(); this.serializer = serializer; allocatedMemory = false; dataStruct = (Native.COPYDATASTRUCT)Marshal.PtrToStructure(lpParam, typeof(Native.COPYDATASTRUCT)); var bytes = new byte[dataStruct.cbData]; Marshal.Copy(dataStruct.lpData, bytes, 0, dataStruct.cbData); string rawmessage; using (var stream = new MemoryStream(bytes)) { var b = new BinaryFormatter(); rawmessage = (string)b.Deserialize(stream); } // use helper method to expand the raw message dataGram = serializer.Deserialize <DataGram>(rawmessage); }
/// <summary> /// The implementation of IXDBroadcast, used to broadcast a new message to other processes. This creates a unique /// file on the filesystem. The temporary files are cleaned up after a pre-defined timeout. /// </summary> /// <param name = "channelName"></param> /// <param name = "dataType"></param> /// <param name = "message"></param> private void SendToChannel(string channelName, string dataType, string message) { Validate.That(channelName).IsNotNullOrEmpty(); Validate.That(dataType).IsNotNullOrEmpty(); Validate.That(message).IsNotNullOrEmpty(); // create temporary name string fileName = Guid.NewGuid().ToString(); string folder = GetChannelDirectory(channelName); string filePath = Path.Combine(folder, string.Concat(fileName, ".msg")); // write the message to the temp file, which will trigger listeners in other processes using (var writer = File.CreateText(filePath)) { // write out the channel name and message, this allows for invalid // characters in the channel name. var dataGram = new DataGram(channelName, dataType, message); writer.Write(serializer.Serialize(dataGram)); writer.Flush(); } // return as fast as we can, leaving a clean up task ThreadPool.QueueUserWorkItem(CleanUpMessages, new FileInfo(filePath).Directory); }
void OnNewData(object sender, DataGram dg) { try { if ((dg.Data.Length == 510) && (dg.Data[0] == 1) && (dg.Data[1] < 4)) { int type = dg.Data[1]; int length = (dg.Data[2] | (dg.Data[3] << 8) | (dg.Data[4] << 16) | (dg.Data[5] << 24)); int block = (dg.Data[8] | (dg.Data[9] << 8)); int numBlocks = (length + 499) / 500; if ((_Buffers[type] == null) || !ArrayEquals(_Buffers[type], 0, dg.Data, 2, 6)) { _Buffers[type] = new byte[6 + numBlocks + (numBlocks * 500)]; Array.Copy(dg.Data, 2, _Buffers[type], 0, 6); } if (_Buffers[type][block + 6] != 1) { _Buffers[type][block + 6] = 1; Array.Copy(dg.Data, 10, _Buffers[type], 6 + numBlocks + (block * 500), 500); if (_Handlers[type] != null) { _Handlers[type](); } } } } catch (Exception ex) { if (!_Stop) { _Logger.Error(Resources.ServerError, ex); } } }
/// <summary> /// Constructor used to create a new instance from a DataGram struct. /// </summary> /// <param name = "dataGram">The DataGram instance.</param> public XDMessageEventArgs(DataGram dataGram) { this.dataGram = dataGram; }
void OnNewData(object sender, DataGram dg) { WorkingThread.Enqueue("Cluster OnNewData", () => { try { using (MemoryStream ms = new MemoryStream(dg.Data)) { BinaryFormatter bf = new BinaryFormatter(); object msg = bf.Deserialize(ms); if (msg is MsgType) { switch ((MsgType)msg) { case MsgType.Activate: Logger.Info <Cluster>(Resources.RemoteActivateAsk); InternalActivate(); break; case MsgType.Deactivate: Logger.Info <Cluster>(Resources.RemoteDeactivateAsk); Deactivate(); break; case MsgType.GetState: MemoryStream info = new MemoryStream(); bf.Serialize(info, _State); if (_Comm != null) { _Comm.Send(dg.Client, info.ToArray()); } break; default: throw new Exception(Resources.UnknownMsgType); } } else if (msg is NodeInfo) { if (_State.RemoteNode.State == NodeState.NoValid) { Logger.Info <Cluster>(String.Format(Resources.ReceivedRemoteNodeState.Replace("\\n", Environment.NewLine), msg)); } else { Logger.Trace <Cluster>(String.Format(Resources.ReceivedRemoteNodeState.Replace("\\n", Environment.NewLine), msg)); } _State.RemoteNode.UpdateInfo((NodeInfo)msg); _RemoteStateTime = DateTime.Now; } else { throw new Exception(Resources.UnknownMsgType); } } } catch (Exception ex) { Logger.Exception <Cluster>(ex); } }); }
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="dg"></param> void OnNewData(object sender, DataGram dg) { try { BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(dg.Data); object msg = bf.Deserialize(ms); lock (_Sync) { if (msg is MsgType) { switch ((MsgType)msg) { case MsgType.Activate: LogHelper.Log(LogLevel.Info, Resources.RemoteActivateAsk); Activate(true); break; case MsgType.Deactivate: LogHelper.Log(LogLevel.Info, Resources.RemoteDeactivateAsk); Deactivate(); break; case MsgType.GetState: MemoryStream info = new MemoryStream(); bf.Serialize(info, _State); if (_Comm != null) { _Comm.Send(dg.Client, info.ToArray()); } break; default: throw new Exception(Resources.UnknownMsgType); } } else if (msg is NodeInfo) { //_Logger.Log((_State.RemoteNode.State == NodeState.NoValid) ? LogLevel.Info : LogLevel.Trace, // Resources.ReceivedRemoteNodeState.Replace("\\n", Environment.NewLine), msg); LogHelper.Log(_State.RemoteNode.State == NodeState.NoValid ? LogLevel.Info : LogLevel.Trace, String.Format(Resources.ReceivedRemoteNodeState.Replace("\\n", Environment.NewLine), msg)); _State.RemoteNode.UpdateInfo((NodeInfo)msg); _RemoteStateTime = DateTime.Now; } else { throw new Exception(Resources.UnknownMsgType); } } } catch (Exception ex) { LogHelper.Log(LogLevel.Error, String.Format("Excepcion en {0}: {1}", Resources.DeleteIpError, ex.Message)); //if (!_Disposed) //{ // _Logger.ErrorException(Resources.NewDataError, ex); //} } }
protected void OnDataReceived(object sender, DataGram dg) { lock (Locker) { SactaMsg.Deserialize(dg.Data, (msg) => { ManageOnLan(sender as UdpSocket, dg.Client.Address, (lan) => { try { if (IsValid(msg)) { switch (msg.Type) { case SactaMsg.MsgType.Init: case SactaMsg.MsgType.Presence: case SactaMsg.MsgType.Sectorization: Logger.Debug <ScvManager>($"On {Cfg.Id} from Sacta Lan {lan} Valid message {msg.Type} received"); if (msg.Type == SactaMsg.MsgType.Init) { // todo } else if (msg.Type == SactaMsg.MsgType.Sectorization) { if (IsSecondSectMsg(msg) == false) { ProccessSectorization(msg, (ok, error) => { // Será llamado por el WorkingThread del servicio PPAL en la gestion del evento que se genere... lock (Locker) { if (ok) { Logger.Info <ScvManager>($"On {Cfg.Id}. Sectorization {msg.Id} Processed."); SendSectAnsw((int)((SactaMsg.SectInfo)(msg.Info)).Version, 1); } else { Logger.Warn <ScvManager>($"On {Cfg.Id}. Sectorization {msg.Id} Rejected => {error}"); SendSectAnsw((int)((SactaMsg.SectInfo)(msg.Info)).Version, 0); } GlobalState = SactaState.SendingPresences; } }); } else { Logger.Info <ScvManager>($"Sectorization Request (Red = {lan}, Versión = {((SactaMsg.SectInfo)(msg.Info)).Version}, IGNORED. Already in Progress..."); } } else { // todo } break; default: Logger.Warn <ScvManager>($"On {Cfg.Id} from Sacta Lan {lan} Invalid message {msg.Type} received"); Logger.Trace <ScvManager>($"On {Cfg.Id} from Sacta Lan {lan} Invalid message received: {msg.ToString()}"); break; } } else { Logger.Warn <ScvManager>($"On {Cfg.Id} from Sacta Lan {lan} Invalid message {msg.Type} received"); Logger.Trace <ScvManager>($"On {Cfg.Id} from Sacta Lan {lan} Invalid message received: {msg.ToString()}"); } } catch (Exception x) { Logger.Exception <ScvManager>(x, $"On {Cfg.Id}"); } }); }, (error) => // Error en el Deserialize. { Logger.Warn <ScvManager>($"On {Cfg.Id} Deserialize Error: {error}"); }); } }
protected void OnDataReceived(object sender, DataGram dg) { lock (Locker) { SactaMsg.Deserialize(dg.Data, (msg) => { ManageOnLan(sender as UdpSocket, (lan) => { try { if (IsValid(msg)) { switch (msg.Type) { case SactaMsg.MsgType.Init: case SactaMsg.MsgType.Presence: case SactaMsg.MsgType.SectAsk: case SactaMsg.MsgType.SectAnswer: Logger.Debug <PsiManager>($"On PSI from Scv Lan {lan} Valid message {msg.Type} received. Id = {msg.Id}"); if (msg.Type == SactaMsg.MsgType.Init) { ScvInfo.LastSectMsgId = -1; } else if (msg.Type == SactaMsg.MsgType.Presence) { } else if (msg.Type == SactaMsg.MsgType.SectAsk) { Logger.Info <PsiManager>($"On PSI from Scv Lan {lan} Sectorization Sectoriztion Request Received"); if (ScvInfo.LastSectMsgId != msg.Id) { // Si el mensaje llega por las dos redes solo respondo una vez... SafeLaunchEvent <SectorizationRequestArgs>(EventSectRequest, new SectorizationRequestArgs()); ScvInfo.LastSectMsgId = msg.Id; } } else if (msg.Type == SactaMsg.MsgType.SectAnswer) { SactaMsg.SectAnswerInfo info = (SactaMsg.SectAnswerInfo)(msg.Info); Logger.Info <PsiManager>($"On PSI from Scv Lan {lan} Sectorization {info.Version} {(info.Result == 1 ? "Accepted" : "Rejected")}."); } break; default: Logger.Warn <PsiManager>($"On PSI from SCV Lan {lan} Invalid message {msg.Type} received"); Logger.Trace <PsiManager>($"On PSI from SCV Lan {lan} Invalid message received: {msg.ToString()}"); break; } } else { Logger.Warn <PsiManager>($"On PSI from SCV Lan {lan} Invalid message {msg.Type} received"); Logger.Trace <PsiManager>($"On PSI from SCV Lan {lan} Invalid message received: {msg.ToString()}"); } } catch (Exception x) { Logger.Exception <PsiManager>(x, $"On PSI"); } }); }, (error) => // Error en el Deserialize. { Logger.Warn <PsiManager>($"On PSI Deserialize Error: {error}"); }); } }