예제 #1
0
            public async Task WhenNackReceivedForMultipleMessage_AllCallbacksAreCalledAndErrorMessagePassed()
            {
                // Arrange
                var client = await GetConnectedClient();

                var callbacks = new List <ValueTuple <bool, ErrorInfo> >();

                var message = new ProtocolMessage(ProtocolMessage.MessageAction.Message, "Test");

                void Callback(bool ack, ErrorInfo err)
                {
                    callbacks.Add((ack, err));
                }

                // Act
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));

                var error = new ErrorInfo("reason", 123);

                client.ExecuteCommand(ProcessMessageCommand.Create(
                                          new ProtocolMessage(ProtocolMessage.MessageAction.Nack)
                {
                    MsgSerial = 0, Count = 3, Error = error
                }));

                await client.ProcessCommands();

                // Assert
                callbacks.Count.Should().Be(3);
                Assert.True(callbacks.TrueForAll(c => !c.Item1));                        // Nack
                Assert.True(callbacks.TrueForAll(c => ReferenceEquals(c.Item2, error))); // Error
            }
예제 #2
0
            public async Task WithNackMessageReceived_CallbackIsCalledWithError()
            {
                // Arrange
                var client = await GetConnectedClient();

                var callbacks = new List <ValueTuple <bool, ErrorInfo> >();
                var message   = new ProtocolMessage(ProtocolMessage.MessageAction.Message, "Test");

                void Callback(bool ack, ErrorInfo err)
                {
                    callbacks.Add((ack, err));
                }

                // Act
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(ProcessMessageCommand.Create(
                                          new ProtocolMessage(ProtocolMessage.MessageAction.Nack)
                {
                    MsgSerial = 0, Count = 1
                }));
                client.ExecuteCommand(SendMessageCommand.Create(message, Callback));
                client.ExecuteCommand(ProcessMessageCommand.Create(
                                          new ProtocolMessage(ProtocolMessage.MessageAction.Nack)
                {
                    MsgSerial = 1, Count = 1
                }));

                await client.ProcessCommands();

                // Assert
                callbacks.Count.Should().Be(2);
                Assert.True(callbacks.TrueForAll(c => c.Item1 == false)); // Nack
                Assert.True(callbacks.TrueForAll(c => c.Item2 != null));  // Error
            }
예제 #3
0
        public void Send(
            ProtocolMessage message,
            Action <bool, ErrorInfo> callback = null,
            ChannelOptions channelOptions     = null)
        {
            if (Logger.IsDebug)
            {
                Logger.Debug($"Current state: {Connection.State}. Sending message: {message}");
            }

            if (message.ConnectionId.IsNotEmpty())
            {
                Logger.Warning(
                    "Setting ConnectionId to null. ConnectionId should never be included in an outbound message on a realtime connection, it’s always implicit");
                message.ConnectionId = null;
            }

            Result result = VerifyMessageHasCompatibleClientId(message);

            if (result.IsFailure)
            {
                callback?.Invoke(false, result.Error);
                return;
            }

            Result encodingResult = Handler.EncodeProtocolMessage(message, channelOptions.ToDecodingContext());

            if (encodingResult.IsFailure)
            {
                Logger.Error($"Failed to encode protocol message: {encodingResult.Error.Message}");
            }

            if (State.CanSend == false && State.CanQueue == false)
            {
                throw new AblyException($"The current state [{State.State}] does not allow messages to be sent.");
            }

            if (State.CanSend == false && State.CanQueue && Options.QueueMessages == false)
            {
                throw new AblyException(
                          $"Current state is [{State.State}] which supports queuing but Options.QueueMessages is set to False.",
                          Connection.ConnectionState.DefaultErrorInfo.Code,
                          HttpStatusCode.ServiceUnavailable);
            }

            ExecuteCommand(SendMessageCommand.Create(message, callback).TriggeredBy("ConnectionManager.Send()"));

            Result VerifyMessageHasCompatibleClientId(ProtocolMessage protocolMessage)
            {
                var messagesResult = RestClient.AblyAuth.ValidateClientIds(protocolMessage.Messages);
                var presenceResult = RestClient.AblyAuth.ValidateClientIds(protocolMessage.Presence);

                return(Result.Combine(messagesResult, presenceResult));
            }
        }
예제 #4
0
            public async Task WhenSendingNotAPresenceOrDataMessage_MsgSerialNotIncremented(
                ProtocolMessage.MessageAction messageAction)
            {
                // Arrange
                var client = await GetConnectedClient();

                var targetMessage1 = new ProtocolMessage(messageAction, "Test");
                var targetMessage2 = new ProtocolMessage(messageAction, "Test");
                var targetMessage3 = new ProtocolMessage(messageAction, "Test");

                client.ExecuteCommand(SendMessageCommand.Create(targetMessage1));
                client.ExecuteCommand(SendMessageCommand.Create(targetMessage2));
                client.ExecuteCommand(SendMessageCommand.Create(targetMessage3));

                await client.ProcessCommands();

                // Assert
                targetMessage1.MsgSerial.Should().Be(0);
                targetMessage2.MsgSerial.Should().Be(0);
                targetMessage3.MsgSerial.Should().Be(0);
            }