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(); }
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() { var authenticationProvider = Mock.Of <IMqttAuthenticationProvider> (p => p.Authenticate(It.IsAny <string>(), It.IsAny <string> (), It.IsAny <string> ()) == true); var sessionRepository = new Mock <IRepository <ClientSession> > (); var willRepository = new Mock <IRepository <ConnectionWill> > (); var senderFlow = new Mock <IPublishSenderFlow> (); var clientId = Guid.NewGuid().ToString(); var connect = new Connect(clientId, cleanSession: true); var willMessage = new FooWillMessage { Message = "Foo Will Message" }; var will = new MqttLastWill("foo/bar", MqttQualityOfService.AtLeastOnce, retain: true, payload: willMessage.GetPayload()); connect.Will = will; var channel = new Mock <IMqttChannel <IPacket> > (); var sentPacket = default(IPacket); channel.Setup(c => c.SendAsync(It.IsAny <IPacket> ())) .Callback <IPacket> (packet => sentPacket = packet) .Returns(Task.Delay(0)); var connectionProvider = new Mock <IConnectionProvider> (); connectionProvider .Setup(p => p.GetConnection(It.Is <string> (c => c == clientId))) .Returns(channel.Object); var flow = new ServerConnectFlow(authenticationProvider, sessionRepository.Object, willRepository.Object, senderFlow.Object); await flow.ExecuteAsync(clientId, connect, channel.Object) .ConfigureAwait(continueOnCapturedContext: false); var 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); Assert.Equal(MqttPacketType.ConnectAck, connectAck.Type); Assert.Equal(MqttConnectionStatus.Accepted, connectAck.Status); Assert.False(connectAck.SessionPresent); }