Exemple #1
0
        [Ignore] //TODO #318
        public async Task MqttWebSocketClientAndServerScenario()
        {
            var websocket = new ClientWebSocket();

            websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Mqtt);
            Uri uri = new Uri("ws://" + IotHubName + ":" + Port + WebSocketConstants.UriSuffix);
            await websocket.ConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);

            var clientReadListener = new ReadListeningHandler();

            using var clientChannel = new ClientWebSocketChannel(null, websocket);
            clientChannel
            .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
            .Option(ChannelOption.AutoRead, true)
            .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
            .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default);

            clientChannel.Pipeline.AddLast(
                MqttEncoder.Instance,
                new MqttDecoder(false, 256 * 1024),
                clientReadListener);
            var clientWorkerGroup = new MultithreadEventLoopGroup();
            await clientWorkerGroup.RegisterAsync(clientChannel).ConfigureAwait(false);

            await Task.WhenAll(RunMqttClientScenarioAsync(clientChannel, clientReadListener), RunMqttServerScenarioAsync(serverWebSocketChannel, serverListener)).ConfigureAwait(false);

            done = true;
        }
        private async Task <RegistrationOperationStatus> ProvisionOverWssCommonAsync(
            ProvisioningTransportRegisterMessage message,
            X509Certificate2 clientCertificate,
            CancellationToken cancellationToken)
        {
            var tcs = new TaskCompletionSource <RegistrationOperationStatus>();

            var uriBuilder   = new UriBuilder(WsScheme, message.GlobalDeviceEndpoint, Port);
            Uri websocketUri = uriBuilder.Uri;

            using var websocket = new ClientWebSocket();
            websocket.Options.AddSubProtocol(WsMqttSubprotocol);
            if (clientCertificate != null)
            {
                websocket.Options.ClientCertificates.Add(clientCertificate);
            }

            //Check if we're configured to use a proxy server
            try
            {
                if (Proxy != DefaultWebProxySettings.Instance)
                {
                    // Configure proxy server
                    websocket.Options.Proxy = Proxy;
                    if (Logging.IsEnabled)
                    {
                        Logging.Info(this, $"{nameof(ProvisionOverWssUsingX509CertificateAsync)} Setting ClientWebSocket.Options.Proxy: {Proxy}");
                    }
                }
            }
            catch (PlatformNotSupportedException)
            {
                // .NET Core 2.0 doesn't support WebProxy configuration - ignore this setting.
                if (Logging.IsEnabled)
                {
                    Logging.Error(this, $"{nameof(ProvisionOverWssUsingX509CertificateAsync)} PlatformNotSupportedException thrown as .NET Core 2.0 doesn't support proxy");
                }
            }

            await websocket.ConnectAsync(websocketUri, cancellationToken).ConfigureAwait(false);

            var clientChannel = new ClientWebSocketChannel(null, websocket);

            clientChannel
            .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
            .Option(ChannelOption.AutoRead, true)
            .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
            .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
            .Pipeline.AddLast(
                new ReadTimeoutHandler(ReadTimeoutSeconds),
                MqttEncoder.Instance,
                new MqttDecoder(false, MaxMessageSize),
                new LoggingHandler(LogLevel.DEBUG),
                new ProvisioningChannelHandlerAdapter(message, tcs, cancellationToken));

            await s_eventLoopGroup.RegisterAsync(clientChannel).ConfigureAwait(false);

            return(await tcs.Task.ConfigureAwait(false));
        }
        private async Task <RegistrationOperationStatus> ProvisionOverWssUsingX509CertificateAsync(
            ProvisioningTransportRegisterMessage message,
            CancellationToken cancellationToken)
        {
            Debug.Assert(message.Security is SecurityProviderX509);
            cancellationToken.ThrowIfCancellationRequested();

            X509Certificate2 clientCertificate =
                ((SecurityProviderX509)message.Security).GetAuthenticationCertificate();

            var tcs = new TaskCompletionSource <RegistrationOperationStatus>();

            UriBuilder uriBuilder   = new UriBuilder(WsScheme, message.GlobalDeviceEndpoint, Port);
            Uri        websocketUri = uriBuilder.Uri;

            // TODO properly dispose of the ws.
            var websocket = new ClientWebSocket();

            websocket.Options.AddSubProtocol(WsMqttSubprotocol);
            websocket.Options.ClientCertificates.Add(clientCertificate);

            await websocket.ConnectAsync(websocketUri, cancellationToken).ConfigureAwait(false);

            // TODO: use ClientWebSocketChannel.
            var clientChannel = new ClientWebSocketChannel(null, websocket);

            clientChannel
            .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
            .Option(ChannelOption.AutoRead, true)
            .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
            .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
            .Pipeline.AddLast(
                new ReadTimeoutHandler(ReadTimeoutSeconds),
                MqttEncoder.Instance,
                new MqttDecoder(false, MaxMessageSize),
                new ProvisioningChannelHandlerAdapter(message, tcs, cancellationToken));

            await s_eventLoopGroup.RegisterAsync(clientChannel).ConfigureAwait(false);

            return(await tcs.Task.ConfigureAwait(false));
        }
Exemple #4
0
        public async Task TestIsActiveFalseAfterClose()
        {
            var             serverSocketChannel = new TcpServerSocketChannel();
            IEventLoopGroup group = new MultithreadEventLoopGroup(1);

            try
            {
                await group.RegisterAsync(serverSocketChannel);

                await serverSocketChannel.BindAsync(new IPEndPoint(IPAddress.IPv6Loopback, 0));

                Assert.True(serverSocketChannel.IsActive);
                Assert.True(serverSocketChannel.IsOpen);
                await serverSocketChannel.CloseAsync();

                Assert.False(serverSocketChannel.IsOpen);
                Assert.False(serverSocketChannel.IsActive);
            }
            finally
            {
                await group.ShutdownGracefullyAsync(TimeSpan.FromMilliseconds(100), TimeSpan.FromSeconds(1));
            }
        }
Exemple #5
0
        static async Task RunWebSocketServer()
        {
            HttpListenerContext context = await listener.GetContextAsync().ConfigureAwait(false);

            if (!context.Request.IsWebSocketRequest)
            {
                context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                context.Response.Close();
            }

            HttpListenerWebSocketContext webSocketContext = await context.AcceptWebSocketAsync(WebSocketConstants.SubProtocols.Mqtt, 8 * 1024, TimeSpan.FromMinutes(5)).ConfigureAwait(false);

            serverListener         = new ReadListeningHandler();
            serverWebSocketChannel = new ServerWebSocketChannel(null, webSocketContext.WebSocket, context.Request.RemoteEndPoint);
            serverWebSocketChannel
            .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
            .Option(ChannelOption.AutoRead, true)
            .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
            .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default);
            serverWebSocketChannel.Pipeline.AddLast("server logger", new LoggingHandler("SERVER"));
            serverWebSocketChannel.Pipeline.AddLast(
                MqttEncoder.Instance,
                new MqttDecoder(true, 256 * 1024),
                serverListener);
            var workerGroup = new MultithreadEventLoopGroup();
            await workerGroup.RegisterAsync(serverWebSocketChannel).ConfigureAwait(false);

            while (true)
            {
                if (done)
                {
                    break;
                }

                await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false);
            }
        }
Exemple #6
0
        Func <IPAddress[], int, Task <IChannel> > CreateWebSocketChannelFactory(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings, ProductInfo productInfo)
        {
            return(async(address, port) =>
            {
                string additionalQueryParams = "";
#if NETSTANDARD1_3
                // NETSTANDARD1_3 implementation doesn't set client certs, so we want to tell the IoT Hub to not ask for them
                additionalQueryParams = "?iothub-no-client-cert=true";
#endif

                var websocketUri = new Uri(WebSocketConstants.Scheme + iotHubConnectionString.HostName + ":" + WebSocketConstants.SecurePort + WebSocketConstants.UriSuffix + additionalQueryParams);
                var websocket = new ClientWebSocket();
                websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Mqtt);

                // Check if we're configured to use a proxy server
                IWebProxy webProxy = settings.Proxy;

                try
                {
                    if (webProxy != DefaultWebProxySettings.Instance)
                    {
                        // Configure proxy server
                        websocket.Options.Proxy = webProxy;
                        if (Logging.IsEnabled)
                        {
                            Logging.Info(this, $"{nameof(CreateWebSocketChannelFactory)} Setting ClientWebSocket.Options.Proxy");
                        }
                    }
                }
                catch (PlatformNotSupportedException)
                {
                    // .NET Core 2.0 doesn't support proxy. Ignore this setting.
                    if (Logging.IsEnabled)
                    {
                        Logging.Error(this, $"{nameof(CreateWebSocketChannelFactory)} PlatformNotSupportedException thrown as .NET Core 2.0 doesn't support proxy");
                    }
                }

                if (settings.ClientCertificate != null)
                {
                    websocket.Options.ClientCertificates.Add(settings.ClientCertificate);
                }

                using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                {
                    await websocket.ConnectAsync(websocketUri, cancellationTokenSource.Token).ConfigureAwait(false);
                }

                var clientChannel = new ClientWebSocketChannel(null, websocket);
                clientChannel
                .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
                .Option(ChannelOption.AutoRead, false)
                .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
                .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
                .Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(false, MaxMessageSize),
                    this.mqttIotHubAdapterFactory.Create(this, iotHubConnectionString, settings, productInfo));
                await s_eventLoopGroup.RegisterAsync(clientChannel).ConfigureAwait(false);

                return clientChannel;
            });
        }