/// <summary> /// Processes a message. /// </summary> /// <param name="address">The address the message was sent from.</param> /// <param name="data">The data to be decoded and processed.</param> private void ProcessMessage(NodeDefinition address, byte[] data) { Message message = new Message(address, data); Logger.Log("Received message of type " + message.Data.GetType().Name + " from " + message.Address.ConnectionName, LogLevel.Debug); // If the message is in response to another message, then don't send an event. // Also, if the message is a Heartbeat, we don't need to do anything, // the last connection time should have been updated when it was received. if (message.InResponseTo != 0) { lock (_waitingForResponses) { if (_waitingForResponses.ContainsKey(message.InResponseTo)) { Message waiting = _waitingForResponses[message.InResponseTo].Item1; waiting.Response = message; waiting.Status = MessageStatus.ResponseReceived; if (waiting.ResponseCallback != null) { _messageReceivedThreadPool.QueueWorkItem(waiting.ResponseCallback, waiting); } _waitingForResponses.Remove(message.InResponseTo); } } } else if (!(message.Data is Heartbeat)) { _messageReceivedThreadPool.QueueWorkItem(MessageReceivedHandler, message); } }
/// <summary> /// Marks the connection as established. /// </summary> /// <param name="def">The node definition, only used for logging at the moment.</param> /// <param name="type">The node type that the connection is to.</param> public void ConnectionEstablished(NodeDefinition def, NodeType type) { NodeType = type; Status = ConnectionStatus.Connected; Logger.Log("Connected to " + Enum.GetName(typeof(NodeType), type) + " node at " + def.ConnectionName, LogLevel.Info); }
/// <summary> /// Process a connection request. /// </summary> /// <param name="result">The result of the connection listener.</param> private void ProcessConnectionRequest(IAsyncResult result) { TcpClient incoming; try { incoming = _connectionListener.EndAcceptTcpClient(result); _connectionListener.BeginAcceptTcpClient(ProcessConnectionRequest, null); } catch (ObjectDisposedException) { // The connection listener was shutdown, stop the async loop. return; } Connection connection = new Connection(incoming); _connectionsLock.EnterWriteLock(); NodeDefinition def = new NodeDefinition(((IPEndPoint)incoming.Client.RemoteEndPoint).Address.ToString(), ((IPEndPoint)incoming.Client.RemoteEndPoint).Port); _connections.Add(def, connection); _connectionsLock.ExitWriteLock(); }
/// <summary> /// Initializes a new instance of the <see cref="Message"/> class. /// </summary> /// <param name="address">The address the message is to be sent to.</param> /// <param name="data">The data to be sent in the message.</param> /// <param name="waitingForResponse">Whether the message is waiting for a response.</param> public Message(NodeDefinition address, BaseMessageData data, bool waitingForResponse) { _address = address; _data = data; _status = MessageStatus.Created; _id = GetNextId(); _waitingForResponse = waitingForResponse; }
/// <summary> /// Initializes a new instance of the <see cref="Message"/> class. /// </summary> /// <param name="responseTo">The message this is in response to.</param> /// <param name="data">The data to be sent in the message.</param> /// <param name="waitingForResponse">Whether the message is waiting for a response.</param> public Message(Message responseTo, BaseMessageData data, bool waitingForResponse) { _address = responseTo.Address; _inResponseTo = responseTo._id; _data = data; _status = MessageStatus.Created; _id = GetNextId(); _waitingForResponse = waitingForResponse; }
/// <summary> /// Renames a connection. /// </summary> /// <param name="currentName">The current name of the connection.</param> /// <param name="newName">The new name of the connection.</param> protected void RenameConnection(NodeDefinition currentName, NodeDefinition newName) { if (Equals(currentName, newName)) { return; } // MAKE SURE THIS LOCK ORDER IS THE SAME EVERYWHERE _connectionsLock.EnterWriteLock(); lock (_messagesReceived) { if (_connections.ContainsKey(currentName)) { // Most likely means that a node disconnected and is trying to reconnect before the connection timeout time. if (_connections.ContainsKey(newName)) { _connections.Remove(newName); } if (_messagesReceived.ContainsKey(newName)) { _messagesReceived.Remove(newName); } var connectionValue = _connections[currentName]; _connections.Remove(currentName); _connections.Add(newName, connectionValue); if (_messagesReceived.ContainsKey(currentName)) { var messageValue = _messagesReceived[currentName]; _messagesReceived.Remove(currentName); _messagesReceived.Add(newName, messageValue); } } } _connectionsLock.ExitWriteLock(); }
/// <summary> /// Called when a connection is lost. /// </summary> /// <param name="node">The connection that was lost.</param> /// <param name="type">The node type that was lost.</param> protected abstract void ConnectionLost(NodeDefinition node, NodeType type);
/// <summary> /// Initializes a new instance of the <see cref="Message"/> class. /// </summary> /// <param name="address">The address this message is from.</param> /// <param name="data">The message data to decode.</param> internal Message(NodeDefinition address, byte[] data) { _address = address; DecodeMessage(data); _status = MessageStatus.Received; }