Example #1
0
        private async Task ReceiveSingleMessageUsingCallbackAsync(TestDeviceType type, Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false);

            using DeviceClient deviceClient     = testDevice.CreateDeviceClient(transport);
            using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger);

            using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger);
            using (msg)
            {
                await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false);

                testDeviceCallbackHandler.ExpectedMessageSentByService = msg;

                using var cts = new CancellationTokenSource(s_tenSeconds);
                Logger.Trace($"Sending C2D message from service, messageId={msg.MessageId}");
                await Task
                .WhenAll(
                    serviceClient.SendAsync(testDevice.Id, msg),
                    testDeviceCallbackHandler.WaitForReceiveMessageCallbackAsync(cts.Token))
                .ConfigureAwait(false);
            }

            await deviceClient.CloseAsync().ConfigureAwait(false);

            await serviceClient.CloseAsync().ConfigureAwait(false);
        }
Example #2
0
        private async Task DoNotReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceType type, ITransportSettings[] settings)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false);

            DeviceClient deviceClient = testDevice.CreateDeviceClient(settings);
            var          testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger);

            using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger);

            // Subscribe to receive C2D messages over the callback.
            await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false);

            // Now dispose and reinitialize the client instance.
            deviceClient.Dispose();
            deviceClient = null;

            testDeviceCallbackHandler.Dispose();
            testDeviceCallbackHandler = null;

            deviceClient = testDevice.CreateDeviceClient(settings);
            testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger);

            // Open the device client - for MQTT, this will connect the device with CleanSession flag set to true.
            // This will ensure that messages sent before the device had subscribed to c2d topic are not delivered.
            await deviceClient.OpenAsync().ConfigureAwait(false);

            // Send the message from service.
            Logger.Trace($"Sending C2D message from service, messageId={msg.MessageId}");
            await serviceClient.SendAsync(testDevice.Id, msg).ConfigureAwait(false);

            // Subscribe to receive C2D messages over the callback.
            testDeviceCallbackHandler.ExpectedMessageSentByService = msg;
            await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false);

            // Wait to ensure that the message was not received.
            using var cts = new CancellationTokenSource(s_tenSeconds);
            Func <Task> receiveMessageOverCallback = async() =>
            {
                await testDeviceCallbackHandler.WaitForReceiveMessageCallbackAsync(cts.Token).ConfigureAwait(false);
            };

            receiveMessageOverCallback.Should().Throw <OperationCanceledException>();

            await serviceClient.CloseAsync().ConfigureAwait(false);

            deviceClient.Dispose();
            testDeviceCallbackHandler.Dispose();
        }
Example #3
0
        private async Task ReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceType type, Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false);

            DeviceClient deviceClient = testDevice.CreateDeviceClient(transport);
            var          testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger);

            using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger);

            // Subscribe to receive C2D messages over the callback.
            await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false);

            // Now dispose and reinitialize the client instance.
            deviceClient.Dispose();
            deviceClient = null;

            testDeviceCallbackHandler.Dispose();
            testDeviceCallbackHandler = null;

            deviceClient = testDevice.CreateDeviceClient(transport);
            testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger);

            // Open the device client - for MQTT, this will connect the device with CleanSession flag set to false.
            await deviceClient.OpenAsync().ConfigureAwait(false);

            // Send the message from service.
            Logger.Trace($"Sending C2D message from service, messageId={msg.MessageId}");
            await serviceClient.SendAsync(testDevice.Id, msg).ConfigureAwait(false);

            // Subscribe to receive C2D messages over the callback.
            testDeviceCallbackHandler.ExpectedMessageSentByService = msg;
            await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false);

            // Wait to ensure that the message was received.
            using var cts = new CancellationTokenSource(s_tenSeconds);
            await testDeviceCallbackHandler.WaitForReceiveMessageCallbackAsync(cts.Token).ConfigureAwait(false);

            await serviceClient.CloseAsync().ConfigureAwait(false);

            deviceClient.Dispose();
            testDeviceCallbackHandler.Dispose();
        }
Example #4
0
        private async Task ReceiveMessageUsingCallbackAndUnsubscribeAsync(TestDeviceType type, Client.TransportType transport)
        {
            TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false);

            using DeviceClient deviceClient     = testDevice.CreateDeviceClient(transport);
            using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger);

            using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString);

            // For Mqtt - we will need to subscribe to the Mqtt receive telemetry topic
            // before the device can begin receiving c2d messages.
            if (transport == Client.TransportType.Mqtt_Tcp_Only ||
                transport == Client.TransportType.Mqtt_WebSocket_Only)
            {
                Client.Message leftoverMessage = await deviceClient.ReceiveAsync(s_fiveSeconds).ConfigureAwait(false);

                Logger.Trace($"Leftover message on Mqtt was: {leftoverMessage} with Id={leftoverMessage?.MessageId}");
            }

            // First receive message using the polling ReceiveAsync() API.
            (Message firstMessage, _, _) = ComposeC2dTestMessage(Logger);
            await serviceClient.SendAsync(testDevice.Id, firstMessage).ConfigureAwait(false);

            Logger.Trace($"Sent C2D message from service, messageId={firstMessage.MessageId} - to be received on polling ReceiveAsync");

            using Client.Message receivedFirstMessage = await deviceClient.ReceiveAsync(s_tenSeconds).ConfigureAwait(false);

            receivedFirstMessage.MessageId.Should().Be(firstMessage.MessageId);
            await deviceClient.CompleteAsync(receivedFirstMessage).ConfigureAwait(false);

            // Now, set a callback on the device client to receive C2D messages.
            await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false);

            // Now, send a message to the device from the service.
            (Message secondMessage, _, _) = ComposeC2dTestMessage(Logger);
            testDeviceCallbackHandler.ExpectedMessageSentByService = secondMessage;
            await serviceClient.SendAsync(testDevice.Id, secondMessage).ConfigureAwait(false);

            Logger.Trace($"Sent C2D message from service, messageId={secondMessage.MessageId} - to be received on callback");

            // The message should be received on the callback, while a call to ReceiveAsync() should return null.
            using var cts = new CancellationTokenSource(s_tenSeconds);
            using Client.Message receivedSecondMessage = await deviceClient.ReceiveAsync(s_tenSeconds).ConfigureAwait(false);

            await testDeviceCallbackHandler.WaitForReceiveMessageCallbackAsync(cts.Token).ConfigureAwait(false);

            receivedSecondMessage.Should().BeNull();

            // Now unsubscribe from receiving c2d messages over the callback.
            await deviceClient.SetReceiveMessageHandlerAsync(null, deviceClient).ConfigureAwait(false);

            // For Mqtt - since we have explicitly unsubscribed, we will need to resubscribe again
            // before the device can begin receiving c2d messages.
            if (transport == Client.TransportType.Mqtt_Tcp_Only ||
                transport == Client.TransportType.Mqtt_WebSocket_Only)
            {
                Client.Message leftoverMessage = await deviceClient.ReceiveAsync(s_fiveSeconds).ConfigureAwait(false);

                Logger.Trace($"Leftover message on Mqtt was: {leftoverMessage} with Id={leftoverMessage?.MessageId}");
            }

            // Send a message to the device from the service.
            (Message thirdMessage, _, _) = ComposeC2dTestMessage(Logger);
            await serviceClient.SendAsync(testDevice.Id, thirdMessage).ConfigureAwait(false);

            Logger.Trace($"Sent C2D message from service, messageId={thirdMessage.MessageId} - to be received on polling ReceiveAsync");

            // This time, the message should not be received on the callback, rather it should be received on a call to ReceiveAsync().
            Func <Task> receiveMessageOverCallback = async() =>
            {
                await testDeviceCallbackHandler.WaitForReceiveMessageCallbackAsync(cts.Token).ConfigureAwait(false);
            };

            using Client.Message receivedThirdMessage = await deviceClient.ReceiveAsync(s_tenSeconds).ConfigureAwait(false);

            receivedThirdMessage.MessageId.Should().Be(thirdMessage.MessageId);
            receiveMessageOverCallback.Should().Throw <OperationCanceledException>();
            await deviceClient.CompleteAsync(receivedThirdMessage).ConfigureAwait(false);

            firstMessage.Dispose();
            secondMessage.Dispose();
            thirdMessage.Dispose();

            await deviceClient.CloseAsync().ConfigureAwait(false);

            await serviceClient.CloseAsync().ConfigureAwait(false);
        }