public Task <bool> MessageReceived(ProtocolMessage protocolMessage, RealtimeState state) { if (protocolMessage.Channel.IsEmpty()) { return(Task.FromResult(false)); } var channel = _channels.Exists(protocolMessage.Channel) ? GetChannel(protocolMessage.Channel) : null; if (channel == null) { Logger.Warning($"Message received {protocolMessage} for a channel that does not exist {protocolMessage.Channel}"); return(Task.FromResult(false)); } switch (protocolMessage.Action) { case ProtocolMessage.MessageAction.Error: channel.SetChannelState(ChannelState.Failed, protocolMessage); break; case ProtocolMessage.MessageAction.Attached: channel.Properties.AttachSerial = protocolMessage.ChannelSerial; if (protocolMessage.Flags.HasValue) { var modes = new ChannelModes(((ProtocolMessage.Flag)protocolMessage.Flags.Value).FromFlag()); channel.Modes = new ReadOnlyChannelModes(modes.ToList()); } if (protocolMessage.Params != null) { channel.Params = new ReadOnlyChannelParams(protocolMessage.Params); } if (channel.State == ChannelState.Attached) { // RTL12 if (!protocolMessage.HasFlag(ProtocolMessage.Flag.Resumed)) { channel.Presence.ChannelAttached(protocolMessage); channel.EmitUpdate(protocolMessage.Error, false, protocolMessage); } } else { channel.SetChannelState(ChannelState.Attached, protocolMessage); } break; case ProtocolMessage.MessageAction.Detach: case ProtocolMessage.MessageAction.Detached: if (channel.State != ChannelState.Detached) { channel.SetChannelState(ChannelState.Detached, protocolMessage); } break; case ProtocolMessage.MessageAction.Message: if (channel.State == ChannelState.Attaching) { Logger.Warning( $"Channel #{channel.Name} is currently in Attaching state. Messages received in this state are ignored. Ignoring ${protocolMessage.Messages?.Length ?? 0} messages"); return(TaskConstants.BooleanTrue); } if (ValidateIfDeltaItHasCorrectPreviousMessageId(protocolMessage, channel.LastSuccessfulMessageIds) == false) { var message = "Delta message decode failure. Previous message id does not equal expected message id."; var reason = new ErrorInfo(message, ErrorCodes.VcDiffDecodeError); channel.StartDecodeFailureRecovery(reason); return(TaskConstants.BooleanTrue); } var result = _messageHandler.DecodeMessages( protocolMessage, protocolMessage.Messages, channel.MessageDecodingContext); if (result.IsFailure) { Logger.Error($"{channel.Name} - failed to decode message. ErrorCode: {result.Error.Code}, Message: {result.Error.Message}"); if (result.Error is VcDiffErrorInfo) { channel.StartDecodeFailureRecovery(result.Error); // Break any further message processing return(TaskConstants.BooleanTrue); } } channel.LastSuccessfulMessageIds = LastMessageIds.Create(protocolMessage); foreach (var msg in protocolMessage.Messages) { channel.OnMessage(msg); } break; case ProtocolMessage.MessageAction.Presence: case ProtocolMessage.MessageAction.Sync: var presenceDecodeResult = _messageHandler.DecodeMessages( protocolMessage, protocolMessage.Presence, channel.Options); if (presenceDecodeResult.IsFailure) { Logger.Error($"{channel.Name} - failed to decode presence message. ErrorCode: {presenceDecodeResult.Error.Code}, Message: {presenceDecodeResult.Error.Message}"); channel.OnError(presenceDecodeResult.Error); } string syncSerial = protocolMessage.Action == ProtocolMessage.MessageAction.Sync ? protocolMessage.ChannelSerial : null; channel.Presence.OnPresence(protocolMessage.Presence, syncSerial); break; } return(Task.FromResult(true)); }
public void ProtocolMessageHasFlagCorrectForNull() { ProtocolMessage.HasFlag(null, ProtocolMessage.Flag.HasPresence).Should().BeFalse(); }
private void MessageReceived(ProtocolMessage protocolMessage) { if (protocolMessage.Channel.IsEmpty()) { return; } var channel = _channels.Exists(protocolMessage.Channel) ? GetChannel(protocolMessage.Channel) : null; if (channel == null) { Logger.Warning($"Message received {protocolMessage} for a channel that does not exist {protocolMessage.Channel}"); return; } switch (protocolMessage.Action) { case ProtocolMessage.MessageAction.Error: channel.SetChannelState(ChannelState.Failed, protocolMessage); break; case ProtocolMessage.MessageAction.Attach: case ProtocolMessage.MessageAction.Attached: if (channel.State == ChannelState.Attached) { // RTL12 if (!protocolMessage.HasFlag(ProtocolMessage.Flag.Resumed)) { channel.EmitUpdate(ChannelState.Attached, protocolMessage); } } else { channel.SetChannelState(ChannelState.Attached, protocolMessage); } break; case ProtocolMessage.MessageAction.Detach: case ProtocolMessage.MessageAction.Detached: if (channel.State != ChannelState.Detached) { channel.SetChannelState(ChannelState.Detached, protocolMessage); } break; case ProtocolMessage.MessageAction.Message: var result = MessageHandler.DecodeProtocolMessage(protocolMessage, channel.Options); if (result.IsFailure) { channel.OnError(result.Error); } foreach (var msg in protocolMessage.Messages) { channel.OnMessage(msg); } break; case ProtocolMessage.MessageAction.Presence: MessageHandler.DecodeProtocolMessage(protocolMessage, channel.Options); channel.Presence.OnPresence(protocolMessage.Presence, null); break; case ProtocolMessage.MessageAction.Sync: MessageHandler.DecodeProtocolMessage(protocolMessage, channel.Options); channel.Presence.OnPresence(protocolMessage.Presence, protocolMessage.ChannelSerial); break; } }
public ChannelStateChange(ChannelEvent e, ChannelState state, ChannelState previous, ErrorInfo error = null, ProtocolMessage protocolMessage = null) : this(e, state, previous, error, false) { ProtocolMessage = protocolMessage; Resumed = protocolMessage != null && protocolMessage.HasFlag(ProtocolMessage.Flag.Resumed); }