private IStoreV1CommunicationData TranslateMessage(ICommunicationMessage message) { if (!m_Converters.ContainsKey(message.GetType())) { throw new UnknownMessageTypeException(); } var converter = m_Converters[message.GetType()]; return(converter.FromMessage(message)); }
/// <summary> /// Sends the given message to the specified endpoint and returns a task that /// will eventually contain the return message. /// </summary> /// <param name="connection">The connection information for the endpoint to which the message has to be send.</param> /// <param name="message">The message that has to be send.</param> /// <param name="maximumNumberOfRetries"> /// The maximum number of times the endpoint will try to send the message if delivery fails. /// </param> /// <param name="timeout">The maximum amount of time the response operation is allowed to take.</param> /// <returns>A task object that will eventually contain the response message.</returns> public Task <ICommunicationMessage> SendMessageToUnregisteredEndpointAndWaitForResponse( EndpointInformation connection, ICommunicationMessage message, int maximumNumberOfRetries, TimeSpan timeout) { { Lokad.Enforce.Argument(() => connection); Lokad.Enforce.Argument(() => message); } using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "ProtocolLayer: sending message and waiting for response")) { var pair = ChannelPairFor(connection); var result = pair.Item2.ForwardResponse(connection.Id, message.Id, timeout); m_Diagnostics.Log( LevelToLog.Trace, CommunicationConstants.DefaultLogTextPrefix, string.Format( CultureInfo.InvariantCulture, "Sending msg of type {0} to endpoint ({1}) while waiting for the response.", message.GetType(), connection)); pair.Item1.Send(connection.ProtocolInformation, message, maximumNumberOfRetries); RaiseOnConfirmChannelIntegrity(connection.Id); return(result); } }
/// <summary> /// Sends the given message to the specified endpoint. /// </summary> /// <param name="connection">The connection information for the endpoint to which the message has to be send.</param> /// <param name="message">The message that has to be send.</param> /// <param name="maximumNumberOfRetries">The maximum number of times the endpoint will try to send the message if delivery fails.</param> /// <exception cref="FailedToSendMessageException"> /// Thrown when the channel fails to deliver the message to the remote endpoint. /// </exception> public void SendMessageToUnregisteredEndpoint(EndpointInformation connection, ICommunicationMessage message, int maximumNumberOfRetries) { { Lokad.Enforce.Argument(() => connection); Lokad.Enforce.Argument(() => message); } using (m_Diagnostics.Profiler.Measure( CommunicationConstants.TimingGroup, "ProtocolLayer: sending message without waiting for response")) { var channel = ChannelFor(connection); m_Diagnostics.Log( LevelToLog.Trace, CommunicationConstants.DefaultLogTextPrefix, string.Format( CultureInfo.InvariantCulture, "Sending msg of type {0} to endpoint ({1}) without waiting for the response.", message.GetType(), connection.Id)); channel.Send(connection.ProtocolInformation, message, maximumNumberOfRetries); RaiseOnConfirmChannelIntegrity(connection.Id); } }
public bool PassThrough(ICommunicationMessage message) { return((message != null) && m_MessageType.IsAssignableFrom(message.GetType())); }
private static bool IsMessageIndicatingEndpointDisconnect(ICommunicationMessage message) { return(message.GetType().Equals(typeof(EndpointDisconnectMessage))); }
/// <summary> /// Processes the message and invokes the desired functions based on the /// message contents or type. /// </summary> /// <param name="message">The message that should be processed.</param> public void ProcessMessage(ICommunicationMessage message) { { Lokad.Enforce.Argument(() => message); } using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "MessageHandler: processing message")) { // Confirm that the endpoint is still alive. RaiseOnConfirmChannelIntegrity(message.Sender); // First check that the message isn't a response. If it is then we see if we have a // waiting task for that. If not then the message will just disappear in the void if (!message.InResponseTo.Equals(MessageId.None)) { m_Diagnostics.Log( LevelToLog.Trace, CommunicationConstants.DefaultLogTextPrefix, string.Format( CultureInfo.InvariantCulture, "Message [{0}] is a response to message [{1}].", message.Id, message.InResponseTo)); using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "Processing response message")) { Tuple <EndpointId, Subject <ICommunicationMessage>, CancellationTokenSource> source = null; lock (m_Lock) { if (m_TasksWaitingForResponse.ContainsKey(message.InResponseTo)) { source = m_TasksWaitingForResponse[message.InResponseTo]; } } // Invoke the OnNext and OnCompleted outside the lock because the setting of the // result may lead to other messages being send and more responses // being required to be handled. All of that may need access to the lock. if (source != null) { source.Item2.OnNext(message); source.Item2.OnCompleted(); } return; } } // Need to do message filtering here // Only accept messages from endpoints that we know of (and have accepted) or // messages that are handshakes / responses to handshakes if (!ShouldProcessMessage(message)) { return; } using (m_Diagnostics.Profiler.Measure(CommunicationConstants.TimingGroup, "Using message filters")) { // The message isn't a response so go to the filters // First copy the filters and their associated actions so that we can // invoke the actions outside the lock. This is necessary because // a message might invoke the requirement for more messages and eventual // responses. Setting up a response requires that we can take out the lock // again. // Once we have the filters then we can just run past all of them and invoke // the actions based on the filter pass through. Dictionary <IMessageFilter, IMessageProcessAction> localCollection; lock (m_Lock) { localCollection = new Dictionary <IMessageFilter, IMessageProcessAction>(m_Filters); } foreach (var pair in localCollection) { if (pair.Key.PassThrough(message)) { m_Diagnostics.Log( LevelToLog.Trace, CommunicationConstants.DefaultLogTextPrefix, string.Format( CultureInfo.InvariantCulture, "Processing message of type {0} with action of type {1}.", message.GetType(), pair.Value.GetType())); pair.Value.Invoke(message); // Each message type should only be procesed by one process action // so if we find it, then we're done. return; } } } // The message type is unknown. See if the last chance handler wants it ... if (m_LastChanceProcessor != null) { m_LastChanceProcessor.Invoke(message); } } }