private void RelayPing(MessageBase message) { var m = message as PingReqMessage; if (m.CorrelationId.HasValue) { _logger.LogInformation( $"Relaying PING {m.SourceNode} -> {m.SubjectNode}"); CorrelatedMessages.TryAdd(m.CorrelationId.Value, m); _swimProtocolProvider.SendMessage(m.SubjectNode, new PingMessage(m.CorrelationId.Value) { SourceNode = _swimProtocolProvider.Node }); } }
private void HandleMessage(MessageBase message) { Debug.WriteLine($"Processing {message.MessageType} Message from {message.SourceNode?.Endpoint ?? "unidentified node"}"); Logger.LogInformation($"Processing {message.MessageType} Message from {message.SourceNode?.Endpoint ?? "unidentified node"}"); try { switch (message.MessageType) { case MessageType.Composite: { var cm = message as CompositeMessage; if (cm.Messages != null) { foreach (var em in cm.Messages) { HandleMessage(em); } } } break; case MessageType.Alive: { lock (_nodesLock) { if (!Nodes.Any(x => x == message.SourceNode)) { AddNode(message.SourceNode); } } AddBroadcastMessage(message); } break; case MessageType.Dead: { lock (_nodesLock) { if (Nodes.Any(x => x == message.SourceNode)) { RemoveNode(message.SourceNode); } } AddBroadcastMessage(message); } break; case MessageType.Ping: { lock (_nodesLock) { if (!Nodes.Any(x => x == message.SourceNode)) { AddNode(message.SourceNode); } } if (message.SourceNode != null && ProtocolProvider?.Node?.Endpoint != null) { ProtocolProvider.SendMessage(message.SourceNode, new AckMessage(message.CorrelationId, ProtocolProvider.Node)); } } break; case MessageType.Ack: { if (message.SourceNode == ActiveNode) { lock (_receivedAckLock) { ReceivedAck = true; } } if (message.CorrelationId.HasValue) { MessageBase ms = null; // Send message back to originating node. if (CorrelatedMessages.TryRemove(message.CorrelationId.Value, out ms)) { var cm = ms as PingReqMessage; ProtocolProvider.SendMessage(cm.SourceNode, message); } } } break; case MessageType.PingReq: { var m = message as PingReqMessage; if (m.CorrelationId.HasValue) { CorrelatedMessages.TryAdd(m.CorrelationId.Value, m); } ProtocolProvider.SendMessage(m.Endpoint, new PingMessage(m.CorrelationId.Value) { SourceNode = ProtocolProvider.Node }); } break; default: Debug.WriteLine($"Unknown message type {message.MessageType}, skipping..."); Logger.LogWarning($"Unknown message type {message.MessageType}, skipping..."); break; } } catch (Exception e) { Debug.WriteLine($"{e.ToString()}: {e.StackTrace}"); Logger.LogError(e, string.Empty); } }
private void _swimProtocolProvider_ReceivedMessage(object sender, ReceivedMessageEventArgs e) { try { foreach (var signedMessage in e.CompositeMessage.Messages) { if (!signedMessage.IsValid()) { _logger.LogError("Signature check failed!"); continue; } var messageType = signedMessage.Message.MessageType; var message = signedMessage.Message; if (message.IsValid) { switch (messageType) { case MessageType.Alive: { if (AddBroadcastMessage(signedMessage)) { var casted = message as AliveMessage; if (casted != null) { _logger.LogInformation( $"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} ALIVE"); AddNode(casted.SubjectNode); } } } break; case MessageType.Dead: { if (AddBroadcastMessage(signedMessage)) { var casted = message as DeadMessage; if (casted != null) { _logger.LogInformation( $"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} SUSPECT"); RemoveNode(casted.SubjectNode); } } } break; case MessageType.Ping: { SendAck(message); AddNode(message.SourceNode); } break; case MessageType.PingReq: { RelayPing(message); } break; case MessageType.Suspect: { if (AddBroadcastMessage(signedMessage)) { var casted = message as SuspectMessage; _logger.LogInformation($"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} SUSPECT"); MarkNodeSuspicious(casted.SubjectNode); } } break; case MessageType.Ack: { HandleAck(message); AddNode(message.SourceNode); MessageBase ms = null; // Send swimMessage back to originating node. if (message.CorrelationId.HasValue && CorrelatedMessages.TryRemove(message.CorrelationId.Value, out ms)) { var cm = ms as PingReqMessage; _logger.LogInformation( $"Relaying ACK {message.SourceNode} -> {cm.SourceNode}"); _swimProtocolProvider.SendMessage(cm.SourceNode, message); } } break; } } _logger.LogInformation($"Received: {JsonConvert.SerializeObject(message)}"); } } catch (Exception ex) { _logger.LogError(ex, "Exception during receive message"); } }