private void ForwardMessageToClient(string clientResponseReceiverId, string serviceResponseReceiverId, object serializedMessage, object originalMessage) { using (EneterTrace.Entering()) { // Check if the requested client id has a connection with the service session which forwards the message. // Note: this is to prevent that a sevice sends a message to a client which is not connected to it. TClientContext aClientContext; using (ThreadLock.Lock(myConnectionLock)) { aClientContext = myConnectedClients.FirstOrDefault(x => x.ClientResponseReceiverId == clientResponseReceiverId && x.ServiceResponseReceiverId == serviceResponseReceiverId); } if (aClientContext == null) { // The associated client does not exist and the message canno be sent. EneterTrace.Warning(TracedObject + "failed to forward the message to client because the client was not found."); return; } IDuplexInputChannel anInputChannel = myClientConnector.AttachedDuplexInputChannel; if (anInputChannel != null) { // Invoke sending of the message in the client particular thread. // So that e.g. if there are communication problems sending to other clients // is not affected. aClientContext.ForwardToClientThreadDispatcher.Invoke( () => { using (EneterTrace.Entering()) { try { anInputChannel.SendResponseMessage(clientResponseReceiverId, serializedMessage); // If originalMessage is null then service forwards just confirmation the connection was open. if (originalMessage == null && ClientConnected != null) { MessageBusClientEventArgs anEvent = new MessageBusClientEventArgs(aClientContext.ServiceId, aClientContext.ServiceResponseReceiverId, clientResponseReceiverId); try { ClientConnected(this, anEvent); } catch (Exception err) { EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err); } } // If original message is not null then the service sends a response message to the client. else if (originalMessage != null && MessageToClientSent != null) { MessageBusMessageEventArgs anEventArgs = new MessageBusMessageEventArgs(aClientContext.ServiceId, serviceResponseReceiverId, clientResponseReceiverId, originalMessage); try { MessageToClientSent(this, anEventArgs); } catch (Exception err) { EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err); } } } catch (Exception err) { string anErrorMessage = TracedObject + "failed to send message to the client."; EneterTrace.Error(anErrorMessage, err); UnregisterClient(aClientContext.ClientResponseReceiverId, true, true); } } }); } } }
private void UnregisterClient(string clientResponseReceiverId, bool sendCloseConnectionToServiceFlag, bool disconnectClientFlag) { using (EneterTrace.Entering()) { // Unregistering client. TClientContext aClientContext = null; using (ThreadLock.Lock(myConnectionLock)) { myConnectedClients.RemoveWhere(x => { if (x.ClientResponseReceiverId == clientResponseReceiverId) { aClientContext = x; return(true); } return(false); }); } if (aClientContext != null) { if (sendCloseConnectionToServiceFlag) { try { // Send close connection message to the service. MessageBusMessage aMessage = new MessageBusMessage(EMessageBusRequest.DisconnectClient, aClientContext.ClientResponseReceiverId, null); object aSerializedMessage = mySerializer.Serialize <MessageBusMessage>(aMessage); IDuplexInputChannel anInputChannel = myServiceConnector.AttachedDuplexInputChannel; if (anInputChannel != null) { anInputChannel.SendResponseMessage(aClientContext.ServiceResponseReceiverId, aSerializedMessage); } } catch (Exception err) { string anErrorMessage = TracedObject + ErrorHandler.FailedToCloseConnection; EneterTrace.Warning(anErrorMessage, err); } } // Disconnecting the client. if (disconnectClientFlag) { IDuplexInputChannel anInputChannel1 = myClientConnector.AttachedDuplexInputChannel; if (anInputChannel1 != null) { anInputChannel1.DisconnectResponseReceiver(aClientContext.ClientResponseReceiverId); } } if (ClientDisconnected != null) { MessageBusClientEventArgs anEventArgs = new MessageBusClientEventArgs(aClientContext.ServiceId, aClientContext.ServiceResponseReceiverId, clientResponseReceiverId); try { ClientDisconnected(this, anEventArgs); } catch (Exception err) { EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err); } } } } }