public virtual void AttachDuplexInputChannel(IDuplexInputChannel duplexInputChannel) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myDuplexInputChannelManipulatorLock)) { Attach(duplexInputChannel); try { AttachedDuplexInputChannel.StartListening(); } catch (Exception err) { try { DetachDuplexInputChannel(); } catch { // Ignore exception in exception. } EneterTrace.Error(TracedObject + ErrorHandler.FailedToStartListening, err); throw; } } } }
/// <summary> /// Method is called when a response is received from the duplex output channel. /// It wrapps the response and sends the wrapped response to the correct response receiver as the response. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { try { // try to find the response receiver id where the wrapped message should be responded. TDuplexConnection aConnction = null; using (ThreadLock.Lock(myConnections)) { aConnction = myConnections.FirstOrDefault(x => x.DuplexOutputChannel == (IDuplexOutputChannel)sender); } if (aConnction != null) { ISerializer aSerializer = mySerializer.ForResponseReceiver(aConnction.ResponseReceiverId); object aMessage = DataWrapper.Wrap(e.ChannelId, e.Message, aSerializer); AttachedDuplexInputChannel.SendResponseMessage(aConnction.ResponseReceiverId, aMessage); } else { EneterTrace.Warning(TracedObject + "failed to send the response message because the response receiver id does not exist. It is possible the response receiver has already been disconnected."); } } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err); } } }
private IEnumerable <string> Send(string responseReceiverId, object serializedMessage) { using (EneterTrace.Entering()) { if (AttachedDuplexInputChannel == null) { string anErrorMessage = TracedObject + "failed to send the message because the it is not attached to duplex input channel."; EneterTrace.Error(anErrorMessage); throw new InvalidOperationException(anErrorMessage); } try { AttachedDuplexInputChannel.SendResponseMessage(responseReceiverId, serializedMessage); } catch (Exception err) { EneterTrace.Error(TracedObject + "failed to send the message. The client will be disconnected and unsubscribed from all messages.", err); try { // Try to disconnect the client. AttachedDuplexInputChannel.DisconnectResponseReceiver(responseReceiverId); } catch { } // Unsubscribe the failed client. return(Unsubscribe(responseReceiverId, null)); } return(new string[0]); } }
/// <summary> /// It is called when a response message from the service is received. /// The response message must be redirected to the associated client. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnOutputChannelResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { string aResponseReceiverId = null; using (ThreadLock.Lock(myConnectionsLock)) { TConnection aConnection = myOpenConnections.FirstOrDefault(x => x.DuplexOutputChannel.ResponseReceiverId == e.ResponseReceiverId); if (aConnection != null) { aResponseReceiverId = aConnection.ResponseReceiverId; } } if (aResponseReceiverId == null) { EneterTrace.Warning(TracedObject + "could not find receiver for the incoming response message."); return; } using (ThreadLock.Lock(myDuplexInputChannelManipulatorLock)) { // Send the response message via the duplex input channel to the sender. if (AttachedDuplexInputChannel != null) { try { AttachedDuplexInputChannel.SendResponseMessage(aResponseReceiverId, e.Message); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err); } } else { EneterTrace.Error(TracedObject + "cannot send the response message when the duplex input channel is not attached."); } } } }
public void SendResponseMessage(string responseReceiverId, string responseMessage) { using (EneterTrace.Entering()) { if (AttachedDuplexInputChannel == null) { string anError = TracedObject + "failed to send the response message because it is not attached to any duplex input channel."; EneterTrace.Error(anError); throw new InvalidOperationException(anError); } try { AttachedDuplexInputChannel.SendResponseMessage(responseReceiverId, responseMessage); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err); throw; } } }
public virtual void DetachDuplexInputChannel() { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myDuplexInputChannelManipulatorLock)) { if (AttachedDuplexInputChannel != null) { try { AttachedDuplexInputChannel.StopListening(); } finally { AttachedDuplexInputChannel.MessageReceived -= OnRequestMessageReceived; AttachedDuplexInputChannel.ResponseReceiverConnected -= OnResponseReceiverConnected; AttachedDuplexInputChannel.ResponseReceiverDisconnected -= OnResponseReceiverDisconnected; AttachedDuplexInputChannel = null; } } } } }
protected override void OnRequestMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { // Try to deserialize the message. BrokerMessage aBrokerMessage; try { aBrokerMessage = mySerializer.ForResponseReceiver(e.ResponseReceiverId).Deserialize <BrokerMessage>(e.Message); } catch (Exception err) { EneterTrace.Error(TracedObject + "failed to deserialize the message.", err); return; } if (myValidateBrokerRequestCallback != null) { bool isValidated = false; try { isValidated = myValidateBrokerRequestCallback(e.ResponseReceiverId, aBrokerMessage); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.DetectedException, err); } if (!isValidated) { IEnumerable <string> anUnsubscribedMessages = Unsubscribe(e.ResponseReceiverId, null); RaiseClientUnsubscribed(e.ResponseReceiverId, anUnsubscribedMessages); try { AttachedDuplexInputChannel.DisconnectResponseReceiver(e.ResponseReceiverId); } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to disconnect response receiver.", err); } return; } } if (aBrokerMessage.Request == EBrokerRequest.Publish) { if (mySerializer.IsSameForAllResponseReceivers()) { // If only one serializer is used for communication with all clients then // increase the performance by reusing already serialized message. Publish(e.ResponseReceiverId, aBrokerMessage, e.Message); } else { // If there is a serializer per client then the message must be serialized // individually for each subscribed client. Publish(e.ResponseReceiverId, aBrokerMessage, null); } } else if (aBrokerMessage.Request == EBrokerRequest.Subscribe) { Subscribe(e.ResponseReceiverId, aBrokerMessage.MessageTypes); } else if (aBrokerMessage.Request == EBrokerRequest.Unsubscribe) { IEnumerable <string> anUnsubscribedMessages = Unsubscribe(e.ResponseReceiverId, aBrokerMessage.MessageTypes); RaiseClientUnsubscribed(e.ResponseReceiverId, anUnsubscribedMessages); } else if (aBrokerMessage.Request == EBrokerRequest.UnsubscribeAll) { IEnumerable <string> anUnsubscribedMessages = Unsubscribe(e.ResponseReceiverId, null); RaiseClientUnsubscribed(e.ResponseReceiverId, anUnsubscribedMessages); } } }