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:
                if (protocolMessage.Channel.IsNotEmpty())
                {
                    channel.SetChannelState(ChannelState.Failed, protocolMessage);
                }
                break;

            case ProtocolMessage.MessageAction.Attach:
            case ProtocolMessage.MessageAction.Attached:
                if (channel.State != ChannelState.Attached)
                {
                    channel.SetChannelState(ChannelState.Attached, protocolMessage);
                }
                else
                {
                    if (protocolMessage.Error != null)
                    {
                        channel.OnError(protocolMessage.Error);
                    }
                }
                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 = _connectionManager.Handler.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:
                _connectionManager.Handler.DecodeProtocolMessage(protocolMessage, channel.Options);
                channel.Presence.OnPresence(protocolMessage.Presence, null);
                break;

            case ProtocolMessage.MessageAction.Sync:
                _connectionManager.Handler.DecodeProtocolMessage(protocolMessage, channel.Options);
                channel.Presence.OnPresence(protocolMessage.Presence, protocolMessage.ChannelSerial);
                break;
            }
        }
Beispiel #2
0
        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));
        }