示例#1
0
        public async Task when_client_disconnects_unexpectedly_then_will_message_is_sent()
        {
            var client1 = await GetClientAsync();

            var client2 = await GetClientAsync();

            var client3 = await GetClientAsync();

            var topic       = Guid.NewGuid().ToString();
            var qos         = MqttQualityOfService.ExactlyOnce;
            var retain      = true;
            var willMessage = new FooWillMessage {
                Message = "Client 1 has been disconnected unexpectedly"
            };
            var willMessagePayload = willMessage.GetPayload();
            var will = new MqttLastWill(topic, qos, retain, willMessagePayload);

            await client1.ConnectAsync(new MqttClientCredentials(GetClientId()), will);

            await client2.ConnectAsync(new MqttClientCredentials(GetClientId()));

            await client3.ConnectAsync(new MqttClientCredentials(GetClientId()));

            await client2.SubscribeAsync(topic, MqttQualityOfService.AtMostOnce);

            await client3.SubscribeAsync(topic, MqttQualityOfService.AtLeastOnce);

            var willReceivedSignal     = new ManualResetEventSlim(initialState: false);
            var willApplicationMessage = default(MqttApplicationMessage);

            client2.MessageStream.Subscribe((Action <MqttApplicationMessage>)(m =>
            {
                if (m.Topic == topic)
                {
                    willApplicationMessage = m;
                    willReceivedSignal.Set();
                }
            }));
            client3.MessageStream.Subscribe((Action <MqttApplicationMessage>)(m =>
            {
                if (m.Topic == topic)
                {
                    willApplicationMessage = m;
                    willReceivedSignal.Set();
                }
            }));

            //Forces socket disconnection without using protocol Disconnect (Disconnect or Dispose Client method)
            (client1 as MqttClientImpl).Channel.Dispose();

            var willReceived = willReceivedSignal.Wait(2000);

            Assert.True(willReceived);
            Assert.NotNull(willMessage);
            Assert.Equal(topic, willApplicationMessage.Topic);
            Assert.Equal(willMessage.Message, FooWillMessage.GetMessage(willApplicationMessage.Payload).Message);

            client2.Dispose();
            client3.Dispose();
        }
示例#2
0
        public async Task when_client_disconnects_by_protocol_then_will_message_is_not_sent()
        {
            var client1 = await GetClientAsync();

            var client2 = await GetClientAsync();

            var client3 = await GetClientAsync();

            var topic       = Guid.NewGuid().ToString();
            var qos         = MqttQualityOfService.ExactlyOnce;
            var retain      = true;
            var willMessage = new FooWillMessage {
                Message = "Client 1 has been disconnected unexpectedly"
            };
            var will = new MqttLastWill(topic, qos, retain, willMessage.GetPayload());

            await client1.ConnectAsync(new MqttClientCredentials(GetClientId()), will);

            await client2.ConnectAsync(new MqttClientCredentials(GetClientId()));

            await client3.ConnectAsync(new MqttClientCredentials(GetClientId()));

            await client2.SubscribeAsync(topic, MqttQualityOfService.AtMostOnce);

            await client3.SubscribeAsync(topic, MqttQualityOfService.AtLeastOnce);

            var willReceivedSignal = new ManualResetEventSlim(initialState: false);

            client2.MessageStream.Subscribe(m =>
            {
                if (m.Topic == topic)
                {
                    willReceivedSignal.Set();
                }
            });
            client3.MessageStream.Subscribe(m =>
            {
                if (m.Topic == topic)
                {
                    willReceivedSignal.Set();
                }
            });

            await client1.DisconnectAsync();

            var willReceived = willReceivedSignal.Wait(2000);

            Assert.False(willReceived);

            client1.Dispose();
            client2.Dispose();
            client3.Dispose();
        }
        public async Task when_sending_connect_with_will_then_will_is_created_and_ack_is_sent()
        {
            IMqttAuthenticationProvider          authenticationProvider = Mock.Of <IMqttAuthenticationProvider>(p => p.Authenticate(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>()) == true);
            Mock <IRepository <ClientSession> >  sessionRepository      = new Mock <IRepository <ClientSession> >();
            Mock <IRepository <ConnectionWill> > willRepository         = new Mock <IRepository <ConnectionWill> >();

            Mock <IPublishSenderFlow> senderFlow = new Mock <IPublishSenderFlow>();

            string  clientId = Guid.NewGuid().ToString();
            Connect connect  = new Connect(clientId, cleanSession: true, MqttProtocol.SupportedLevel);

            FooWillMessage willMessage = new FooWillMessage {
                Message = "Foo Will Message"
            };
            MqttLastWill will = new MqttLastWill("foo/bar", MqttQualityOfService.AtLeastOnce, retain: true, payload: willMessage.GetPayload());

            connect.Will = will;

            Mock <IMqttChannel <IPacket> > channel = new Mock <IMqttChannel <IPacket> >();
            IPacket sentPacket = default;

            channel.Setup(c => c.SendAsync(It.IsAny <IPacket>()))
            .Callback <IPacket>(packet => sentPacket = packet)
            .Returns(Task.Delay(0));

            Mock <IConnectionProvider> connectionProvider = new Mock <IConnectionProvider>();

            connectionProvider
            .Setup(p => p.GetConnection(It.Is <string>(c => c == clientId)))
            .Returns(channel.Object);

            ServerConnectFlow flow = new ServerConnectFlow(authenticationProvider, sessionRepository.Object, willRepository.Object, senderFlow.Object);

            await flow.ExecuteAsync(clientId, connect, channel.Object);

            ConnectAck connectAck = sentPacket as ConnectAck;

            sessionRepository.Verify(r => r.Delete(It.IsAny <string>()), Times.Never);
            sessionRepository.Verify(r => r.Create(It.Is <ClientSession>(s => s.Id == clientId && s.Clean == true)));
            willRepository.Verify(r => r.Create(It.Is <ConnectionWill>(w => w.Id == clientId && w.Will == will)));

            Assert.NotNull(connectAck);
            connectAck.Type.Should().Be(MqttPacketType.ConnectAck);
            connectAck.Status.Should().Be(MqttConnectionStatus.Accepted);
            Assert.False(connectAck.SessionPresent);
        }