/// <summary> /// Prova ad inviare il messaggio specificato al servizio configurato con la specifica istanza di questa classe. /// </summary> /// <param name="message">La query o la reply da inviare al servizio di un nodo vicino.</param> /// <param name="detection">L'eventuale istante di rilevamento del vicino.</param> /// <returns>true se non si sono vericati errori durante l'invio della query; in caso contrario, false.</returns> /// <remarks> /// Se si verificano errori durante la trasmissione del messaggio al servizio, questo metodo restituisce false /// e imposta il valore predefinito di un oggetto DateTime come istante di rilevazione, pertanto il valore non /// deve essere considerato. Invece, se il metodo restituisce true, vuol dire che non è avvenuto nessun errore /// durante la trasmissione del messaggio e quindi l'istante di rilevazione del servizio è corretto. /// </remarks> private bool TrySendMessage(MessageData message, out DateTime detection) { lock (m_SyncLock) { if (m_ProxyClosed || m_BindingConfig == null || m_RemoteUri == null) { detection = default(DateTime); return false; } try { if (m_InternalProxy == null) { ChannelFactory<IQueryReplyService> factory = new ChannelFactory<IQueryReplyService>(m_BindingConfig, new EndpointAddress(m_RemoteUri)); m_InternalProxy = factory.CreateChannel(); } if (message is QueryData) { WriteToLog("Dispatching query {0} to node {1}...", message.MsgId, m_TargetNodeId); m_InternalProxy.Query(m_NodeId, message as QueryData); } else if (message is ReplyData) { WriteToLog("Dispatching reply {0} to node {1}...", message.MsgId, m_TargetNodeId); m_InternalProxy.Reply(m_NodeId, message as ReplyData); } else { detection = default(DateTime); return false; } detection = DateTime.Now; return true; } catch { if (m_InternalProxy != null) { ICommunicationObject proxy = m_InternalProxy as ICommunicationObject; if (proxy.State == CommunicationState.Faulted) { proxy.Abort(); m_InternalProxy = null; } } detection = default(DateTime); return false; } } }
/// <summary> /// Inserisce il messaggio specificato nella coda di uscita di questo NeighborClient e restituisce true /// se il messaggio è stato effettivamente inserito in coda, altrimenti false se non è stato possibile /// aggiungere il messaggio perché la coda era piena. /// </summary> /// <param name="message">Il messaggio da inserire nella coda di uscita.</param> /// <returns>true se il messaggio è stato inserito in coda; in caso contrario, false.</returns> public bool Enqueue(MessageData message) { lock (m_SyncLock) { if (m_OutputQueue.Count == m_OutputQueueSize) return false; m_OutputQueue.Enqueue(message); Monitor.Pulse(m_SyncLock); // notifica l'unico consumatore } return true; }