private void OnMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { try { using (ThreadLock.Lock(myResponseReceiverContexts)) { TResponseReceiverContext aResponseReceiver = GetResponseReceiver(e.ResponseReceiverId); if (aResponseReceiver == null) { // Note: the response receiver was just disconnected. return; } aResponseReceiver.LastReceiveTime = DateTime.Now; } // Deserialize the incoming message. MonitorChannelMessage aMessage = mySerializer.Deserialize <MonitorChannelMessage>(e.Message); // if the message is ping, then response. if (aMessage.MessageType == MonitorChannelMessageType.Message) { // Notify the incoming message. DuplexChannelMessageEventArgs aMsg = new DuplexChannelMessageEventArgs(e.ChannelId, aMessage.MessageContent, e.ResponseReceiverId, e.SenderAddress); Dispatcher.Invoke(() => NotifyGeneric(MessageReceived, aMsg, true)); } } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToReceiveMessage, err); } } }
public void OpenConnection() { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myConnectionManipulatorLock)) { if (IsConnected) { string aMessage = TracedObject + ErrorHandler.IsAlreadyConnected; EneterTrace.Error(aMessage); throw new InvalidOperationException(aMessage); } myOutputChannel.ConnectionOpened += OnConnectionOpened; myOutputChannel.ConnectionClosed += OnConnectionClosed; myOutputChannel.ResponseMessageReceived += OnResponseMessageReceived; myConnectionOpeningRequestedToStopFlag = false; myConnectionOpeningEndedEvent.Reset(); // Try open connection in a different thread. myConnectionOpeningActiveFlag = true; EneterThreadPool.QueueUserWorkItem(DoOpenConnection); // Indicate the ConnectionOpened event shall be raised when the connection is really open. myIsConnectionOpenEventPendingFlag = true; // Indicate the connection is open. myConnectionIsOpenFlag = true; } DuplexChannelEventArgs anEvent = new DuplexChannelEventArgs(ChannelId, ResponseReceiverId, ""); Dispatcher.Invoke(() => Notify(ConnectionOffline, anEvent, false)); } }
public void OpenConnection(Action <MessageContext> responseMessageHandler) { using (EneterTrace.Entering()) { if (responseMessageHandler == null) { throw new ArgumentNullException("responseMessageHandler is null."); } using (ThreadLock.Lock(myConnectionManipulatorLock)) { try { myResponseMessageHandler = responseMessageHandler; myMessagingProvider.RegisterMessageHandler(myOutputConnectorAddress, HandleResponseMessage); myIsResponseListenerRegistered = true; // Send the open connection request. object anEncodedMessage = myProtocolFormatter.EncodeOpenConnectionMessage(myOutputConnectorAddress); myMessagingProvider.SendMessage(myInputConnectorAddress, anEncodedMessage); myIsConnected = true; } catch { CloseConnection(); throw; } } } }
public void Close(bool waitForSendComplete) { if (waitForSendComplete) { if (_isClosing) { return; } using (var threadLock = new ThreadLock()) { if (threadLock.Lock(IsReceivingLock)) { _isClosing = true; } } var token = _linkedTokenSource.Token; while (_isSending) { WaitHandle.WaitAny(new[] { token.WaitHandle }, 100); } } if (!_linkedTokenSource.IsCancellationRequested) { _linkedTokenSource.Cancel(); } }
public override void DetachDuplexInputChannel() { using (EneterTrace.Entering()) { base.DetachDuplexInputChannel(); // If this is singleton service mode. if (mySingletonService != null) { mySingletonService.DetachInputChannel(); } else { // If per client mode then detach all service stubs. using (ThreadLock.Lock(myPerConnectionServices)) { foreach (KeyValuePair <string, ServiceStub <TServiceInterface> > aServiceStub in myPerConnectionServices) { aServiceStub.Value.UnsubscribeClientFromEvents(aServiceStub.Key); aServiceStub.Value.DetachInputChannel(); } } } } }
public CommandSystem() { mCommandBufferProcess = new List <Command>(); mCommandBufferInput = new List <Command>(); mExecuteList = new List <Command>(); mBufferLock = new ThreadLock(); }
public void Send(byte[] data) { try { var callSendComplete = false; using (var threadLock = new ThreadLock()) { if (!threadLock.Lock(IsSendingLock)) { return; } if (!_linkedTokenSource.IsCancellationRequested) { if (!_isSending && _sendBuffer.Count == 0) { callSendComplete = true; } _sendBuffer.Enqueue(data); } } if (callSendComplete) { SendToClient(); } } catch { // ignored } }
public void OpenConnection() { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myConnectionManipulatorLock)) { if (IsConnected) { string aMessage = TracedObject + ErrorHandler.IsAlreadyConnected; EneterTrace.Error(aMessage); throw new InvalidOperationException(aMessage); } try { // Start timers. myPingingTimer.Change(myPingFrequency); myReceiveTimer.Change(myReceiveTimeout); // Open connection in the underlying channel. myUnderlyingOutputChannel.OpenConnection(); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToOpenConnection, err); CloseConnection(); throw; } } } }
private void CleanConnection(bool sendMessageFlag) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myConnectionManipulatorLock)) { myResponseMessageHandler = null; if (myResponseReceiver != null) { if (sendMessageFlag) { try { byte[] anEncodedMessage = (byte[])myProtocolFormatter.EncodeCloseConnectionMessage(myOutputConnectorAddress); if (anEncodedMessage != null) { myResponseReceiver.SendTo(anEncodedMessage, myServiceEndpoint); } } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to send close connection message.", err); } } myResponseReceiver.StopListening(); myResponseReceiver = null; } } } }
public CommandPool() { mInusedList = new Dictionary <Type, List <Command> >(); mUnusedList = new Dictionary <Type, List <Command> >(); mInuseLock = new ThreadLock(); mUnuseLock = new ThreadLock(); }
private void OnResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e) { using (EneterTrace.Entering()) { try { // Deserialize the message. MonitorChannelMessage aMessage = mySerializer.Deserialize <MonitorChannelMessage>(e.Message); // Note: timer setting is after deserialization. // reason: if deserialization fails the timer is not updated and the client will be disconnected. using (ThreadLock.Lock(myConnectionManipulatorLock)) { // Cancel the current response timeout and set the new one. myReceiveTimer.Change(myReceiveTimeout); } // If it is a message. if (aMessage.MessageType == MonitorChannelMessageType.Message) { Dispatcher.Invoke(() => Notify <DuplexChannelMessageEventArgs>(ResponseMessageReceived, new DuplexChannelMessageEventArgs(e.ChannelId, aMessage.MessageContent, e.ResponseReceiverId, e.SenderAddress), true)); } } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToReceiveMessage, err); } } }
public ClassPool(string name) : base(name) { mInusedList = new Dictionary <Type, List <IClassObject> >(); mUnusedList = new Dictionary <Type, Stack <IClassObject> >(); mListLock = new ThreadLock(); }
private void SendFrame(Func <byte[], byte[]> formatter) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myConnectionManipulatorLock)) { if (!IsConnected) { string aMessage = TracedObject + ErrorHandler.FailedToSendMessageBecauseNotConnected; EneterTrace.Error(aMessage); throw new InvalidOperationException(aMessage); } try { // Encode the message frame. // Note: According to the protocol, server shall not mask sent data. byte[] aFrame = formatter(null); // Send the message. myClientStream.Write(aFrame, 0, aFrame.Length); //myClientStream.Flush(); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendMessage, err); throw; } } } }
public void StartListening() { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myListeningManipulatorLock)) { if (IsListening) { string aMessage = TracedObject + ErrorHandler.IsAlreadyListening; EneterTrace.Error(aMessage); throw new InvalidOperationException(aMessage); } myUnderlyingInputChannel.ResponseReceiverConnected += OnResponseReceiverConnected; myUnderlyingInputChannel.ResponseReceiverDisconnected += OnResponseReceiverDisconnected; myUnderlyingInputChannel.MessageReceived += OnMessageReceived; try { myUnderlyingInputChannel.StartListening(); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToStartListening, err); StopListening(); } } } }
// A client was disconnected from the load balancer. protected override void OnResponseReceiverDisconnected(object sender, ResponseReceiverEventArgs e) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myReceiverManipulatorLock)) { myOpenConnections.RemoveWhere(x => { if (x.ResponseReceiverId == e.ResponseReceiverId) { try { x.DuplexOutputChannel.CloseConnection(); } catch (Exception err) { EneterTrace.Warning(TracedObject + ErrorHandler.FailedToCloseConnection, err); } x.DuplexOutputChannel.ResponseMessageReceived -= OnResponseMessageReceived; x.DuplexOutputChannel.ConnectionClosed -= OnRequestReceiverClosedConnection; return(true); } return(false); }); } Notify(ResponseReceiverDisconnected, e); } }
public void OpenConnection(Action <MessageContext> responseMessageHandler) { using (EneterTrace.Entering()) { if (responseMessageHandler == null) { throw new ArgumentNullException("responseMessageHandler is null."); } using (ThreadLock.Lock(myConnectionManipulatorLock)) { try { myResponseMessageHandler = responseMessageHandler; myResponseReceiver = UdpReceiver.CreateConnectedReceiver(myServiceEndpoint, myReuseAddressFlag, myResponseReceivingPort, myTtl); myResponseReceiver.StartListening(OnResponseMessageReceived); byte[] anEncodedMessage = (byte[])myProtocolFormatter.EncodeOpenConnectionMessage(myOutputConnectorAddress); if (anEncodedMessage != null) { myResponseReceiver.SendTo(anEncodedMessage, myServiceEndpoint); } } catch { CloseConnection(); throw; } } } }
// Removes the request receiver to the pool. public void RemoveDuplexOutputChannel(string channelId) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myReceiverManipulatorLock)) { myAvailableReceivers.Remove(channelId); // Close all open connection with this request receiver. myOpenConnections.RemoveWhere(x => { if (x.DuplexOutputChannel.ChannelId == channelId) { try { // Close connection with the request receiver. x.DuplexOutputChannel.CloseConnection(); } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to close connection to " + channelId, err); } x.DuplexOutputChannel.ConnectionClosed -= OnRequestReceiverClosedConnection; x.DuplexOutputChannel.ResponseMessageReceived -= OnResponseMessageReceived; return(true); } return(false); }); } } }
public void SendBroadcast(object message) { using (EneterTrace.Entering()) { List <string> aDisconnectedClients = new List <string>(); using (ThreadLock.Lock(myConnectedClients)) { foreach (string aClientId in myConnectedClients.Keys) { try { MessageBusMessage aMessage = new MessageBusMessage(EMessageBusRequest.SendResponseMessage, aClientId, message); object aSerializedMessage = mySerializer.Serialize <MessageBusMessage>(aMessage); myMessageBusOutputChannel.SendMessage(aSerializedMessage); } catch (Exception err) { EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err); aDisconnectedClients.Add(aClientId); // Note: Exception is not rethrown because if sending to one client fails it should not // affect sending to other clients. } } } // Disconnect failed clients. foreach (String anOutputConnectorAddress in aDisconnectedClients) { CloseConnection(anOutputConnectorAddress, true); } } }
public void Receive(byte[] dataReceived) { using var threadLock = new ThreadLock(); if (!threadLock.Lock(IsReceivingLock)) { return; } if (_isClosing) { return; } if (_readBufferPointer + dataReceived.Length > _readBuffer.Length) // Buffer Overload { _readBufferPointer = 0; // Empty the buffer return; } Buffer.BlockCopy(dataReceived, 0, _readBuffer, _readBufferPointer, dataReceived.Length); _readBufferPointer += dataReceived.Length; if (Array.IndexOf(dataReceived, Iac) < 0 && Array.IndexOf(dataReceived, Cr) < 0 && Array.IndexOf(dataReceived, Lf) < 0) { return; } var buffer = new byte[_readBufferPointer]; Buffer.BlockCopy(_readBuffer, 0, buffer, 0, _readBufferPointer); ProcessReceivedData(ref buffer); _readBufferPointer = buffer.Length; }
public void StartListening(Action <MessageContext> messageHandler) { using (EneterTrace.Entering()) { if (messageHandler == null) { throw new ArgumentNullException("messageHandler is null."); } using (ThreadLock.Lock(myListeningManipulatorLock)) { try { myMessageHandler = messageHandler; myMessageBusOutputChannel.ResponseMessageReceived += OnMessageFromMessageBusReceived; // Open connection with the message bus. myMessageBusOutputChannel.OpenConnection(); // Register service in the message bus. MessageBusMessage aMessage = new MessageBusMessage(EMessageBusRequest.RegisterService, myServiceId, null); object aSerializedMessage = mySerializer.Serialize <MessageBusMessage>(aMessage); myMessageBusOutputChannel.SendMessage(aSerializedMessage); } catch { StopListening(); throw; } } } }
private void SendToClient() { try { var waitHandle = new AutoResetEvent(false); var token = _linkedTokenSource.Token; while (!_linkedTokenSource.IsCancellationRequested && _sendBuffer.Count > 0) { waitHandle.Reset(); if (!_isSending) { using var threadLock = new ThreadLock(); if (!threadLock.Lock(IsSendingLock)) { return; } if (_sendBuffer.TryDequeue(out var dataToSend)) { _isSending = true; _connection.Transport.Output.WriteAsync(dataToSend, token).AsTask() .ContinueWith(x => { _isSending = false; waitHandle.Set(); }, token); } } WaitHandle.WaitAny(new[] { token.WaitHandle, waitHandle }, 100); } } finally { _isSending = false; } }
/// <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); } } }
protected override void OnResponseReceiverDisconnected(object sender, ResponseReceiverEventArgs e) { using (EneterTrace.Entering()) { if (mySingletonService != null) { mySingletonService.UnsubscribeClientFromEvents(e.ResponseReceiverId); } else { // If per client mode then remove service stub for the disconnected client. using (ThreadLock.Lock(myPerConnectionServices)) { // Unsubscribe disconnected client from all events. ServiceStub <TServiceInterface> aServiceStub; myPerConnectionServices.TryGetValue(e.ResponseReceiverId, out aServiceStub); if (aServiceStub != null) { aServiceStub.UnsubscribeClientFromEvents(e.ResponseReceiverId); aServiceStub.DetachInputChannel(); myPerConnectionServices.Remove(e.ResponseReceiverId); } } } if (ResponseReceiverDisconnected != null) { ResponseReceiverDisconnected(this, e); } } }
private void CleanConnection(bool sendMessageFlag) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myConnectionManipulatorLock)) { if (myResponseReceiver != null) { myResponseReceiver.StopListening(); myResponseReceiver = null; } if (mySender != null) { if (sendMessageFlag) { // Send close connection message. try { object anEncodedMessage = myProtocolFormatter.EncodeCloseConnectionMessage(myOutputConnectorAddress); mySender.SendMessage(anEncodedMessage); } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to send close connection message.", err); } } mySender.Dispose(); mySender = null; } } } }
public void SendMessage(string receiverId, object message) { using (EneterTrace.Entering()) { // Get the message handler Action <object> aMessageHandler = null; using (ThreadLock.Lock(myRegisteredMessageHandlers)) { myRegisteredMessageHandlers.TryGetValue(receiverId, out aMessageHandler); } // If the message handler was found then send the message if (aMessageHandler != null) { Action aHelperCallback = () => { aMessageHandler(message); }; EneterThreadPool.QueueUserWorkItem(aHelperCallback.Invoke); } else { string anError = "The receiver '" + receiverId + "' does not exist."; EneterTrace.Error(anError); throw new InvalidOperationException(anError); } } }
public void OpenConnection(Action <MessageContext> responseMessageHandler) { using (EneterTrace.Entering()) { if (responseMessageHandler == null) { throw new ArgumentNullException("responseMessageHandler is null."); } using (ThreadLock.Lock(myConnectionManipulatorLock)) { try { mySender = new NamedPipeSender(myInputConnectorAddress, myTimeout); myResponseMessageHandler = responseMessageHandler; myResponseReceiver = new NamedPipeReceiver(myOutputConnectorAddress, 1, myTimeout, mySecurity); myResponseReceiver.StartListening(HandleResponseMessages); // Send the open connection request. object anEncodedMessage = myProtocolFormatter.EncodeOpenConnectionMessage(myOutputConnectorAddress); mySender.SendMessage(anEncodedMessage); } catch { CloseConnection(); throw; } } } }
private void CleanConnection(bool sendMessageFlag) { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myConnectionManipulatorLock)) { if (myIsConnected) { if (sendMessageFlag) { // Send close connection message. try { object anEncodedMessage = myProtocolFormatter.EncodeCloseConnectionMessage(myOutputConnectorAddress); myMessagingProvider.SendMessage(myInputConnectorAddress, anEncodedMessage); } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to send close connection message.", err); } } myIsConnected = false; } if (myIsResponseListenerRegistered) { myMessagingProvider.UnregisterMessageHandler(myOutputConnectorAddress); myResponseMessageHandler = null; myIsResponseListenerRegistered = false; } } } }
// Removes all request receivers. public void RemoveAllDuplexOutputChannels() { using (EneterTrace.Entering()) { using (ThreadLock.Lock(myReceiverManipulatorLock)) { myAvailableReceivers.Clear(); // Close all open connections with request receivers. foreach (TConnection aConnection in myOpenConnections) { try { aConnection.DuplexOutputChannel.CloseConnection(); } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to close connection to " + aConnection.DuplexOutputChannel.ChannelId, err); } aConnection.DuplexOutputChannel.ResponseMessageReceived -= OnResponseMessageReceived; aConnection.DuplexOutputChannel.ConnectionClosed -= OnRequestReceiverClosedConnection; } // Clear all open connections. myOpenConnections.Clear(); // Note: Clients (response receivers) stay connected becaue it is still possible to add // new request receivers to the pool. } } }
public void DetachInputChannel() { using (EneterTrace.Entering()) { // Clean subscription for all clients. using (ThreadLock.Lock(myServiceEvents)) { foreach (EventContext anEventContext in myServiceEvents) { try { anEventContext.Unsubscribe(); } catch (Exception err) { EneterTrace.Warning(TracedObject + "failed to unsubscribe from the event '" + anEventContext.EventInfo.Name + "'.", err); } } myServiceEvents.Clear(); } myInputChannel = null; } }
// Note: this method must be available after the dispose. public byte[] DequeueCollectedMessages() { using (EneterTrace.Entering()) { byte[] aDequedMessages = null; using (ThreadLock.Lock(myMessages)) { // Update the polling time. LastPollingActivityTime = DateTime.Now; // If there are stored messages for the receiver if (myMessages.Count > 0) { using (MemoryStream aStreamedResponses = new MemoryStream()) { // Dequeue responses to be sent to the response receiver. // Note: Try not to exceed 1MB - better do more small transfers while (myMessages.Count > 0 && aStreamedResponses.Length < 1048576) { // Get the response message formatted according to the connection protocol. byte[] aResponseMessage = myMessages.Dequeue(); aStreamedResponses.Write(aResponseMessage, 0, aResponseMessage.Length); } aDequedMessages = aStreamedResponses.ToArray(); } } } return(aDequedMessages); } }