Exemplo n.º 1
0
        static void Main(string[] args)
        {
            // optimizing IOCP performance
            int minWorkerThreads;
            int minCompletionPortThreads;

            ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);
            ThreadPool.SetMinThreads(minWorkerThreads, Math.Max(16, minCompletionPortThreads));

            int threadCount = Environment.ProcessorCount;

            if (args.Length > 0)
            {
                threadCount = int.Parse(args[0]);
            }

            var eventListener = new ObservableEventListener();

            eventListener.LogToConsole();
            eventListener.EnableEvents(BootstrapperEventSource.Log, EventLevel.Verbose);
            eventListener.EnableEvents(MqttIotHubAdapterEventSource.Log, EventLevel.Verbose);
            eventListener.EnableEvents(ChannelEventSource.Log, EventLevel.Verbose);
            eventListener.EnableEvents(BootstrapEventSource.Log, EventLevel.Verbose);
            eventListener.EnableEvents(ExecutorEventSource.Log, EventLevel.Verbose);
            eventListener.EnableEvents(MqttEventSource.Log, EventLevel.Verbose);

            try
            {
                var cts = new CancellationTokenSource();

                var certificate      = new X509Certificate2("protocol-gateway.contoso.com.pfx", "password");
                var settingsProvider = new AppConfigSettingsProvider();
                BlobSessionStatePersistenceProvider blobSessionStateProvider = BlobSessionStatePersistenceProvider.CreateAsync(
                    settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageConnectionString"),
                    settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageContainerName")).Result;

                TableQos2StatePersistenceProvider tableQos2StateProvider = TableQos2StatePersistenceProvider.CreateAsync(
                    settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageConnectionString"),
                    settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageTableName")).Result;

                var bootstrapper = new Bootstrapper(settingsProvider, blobSessionStateProvider, tableQos2StateProvider);
                Task.Run(() => bootstrapper.RunAsync(certificate, threadCount, cts.Token), cts.Token);

                while (true)
                {
                    string input = Console.ReadLine();
                    if (input != null && input.ToLowerInvariant() == "exit")
                    {
                        break;
                    }
                }

                cts.Cancel();
                bootstrapper.CloseCompletion.Wait(TimeSpan.FromSeconds(20));
            }
            finally
            {
                eventListener.Dispose();
            }
        }
        async Task EnsureServerInitializedAsync()
        {
            if (this.ServerAddress != null)
            {
                return;
            }

            int threadCount   = Environment.ProcessorCount;
            var executorGroup = new MultithreadEventLoopGroup(threadCount);
            BlobSessionStatePersistenceProvider sessionStateProvider = await BlobSessionStatePersistenceProvider.CreateAsync(
                this.settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageConnectionString"),
                this.settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageContainerName"));

            TableQos2StatePersistenceProvider qos2StateProvider = await TableQos2StatePersistenceProvider.CreateAsync(
                this.settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageConnectionString"),
                this.settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageTableName"));

            var settings             = new Settings(this.settingsProvider);
            var iotHubClientSettings = new IotHubClientSettings(this.settingsProvider);
            var authProvider         = new SasTokenDeviceIdentityProvider();
            var topicNameRouter      = new ConfigurableMessageAddressConverter();

            var iotHubClientFactory = IotHubClient.PreparePoolFactory(iotHubClientSettings.IotHubConnectionString, 400, TimeSpan.FromMinutes(5),
                                                                      iotHubClientSettings, PooledByteBufferAllocator.Default, topicNameRouter);
            MessagingBridgeFactoryFunc bridgeFactory = async identity => new SingleClientMessagingBridge(identity, await iotHubClientFactory(identity));

            ServerBootstrap server = new ServerBootstrap()
                                     .Group(executorGroup)
                                     .Channel <TcpServerSocketChannel>()
                                     .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
                                     .ChildOption(ChannelOption.AutoRead, false)
                                     .ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                ch.Pipeline.AddLast(TlsHandler.Server(this.tlsCertificate));
                ch.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, 256 * 1024),
                    new LoggingHandler("SERVER"),
                    new MqttAdapter(
                        settings,
                        sessionStateProvider,
                        authProvider,
                        qos2StateProvider,
                        bridgeFactory),
                    new XUnitLoggingHandler(this.output));
            }));

            IChannel serverChannel = await server.BindAsync(IPAddress.Any, this.ProtocolGatewayPort);

            this.ScheduleCleanup(async() =>
            {
                await serverChannel.CloseAsync();
                await executorGroup.ShutdownGracefullyAsync();
            });
            this.ServerAddress = IPAddress.Loopback;
        }
Exemplo n.º 3
0
        async Task EnsureServerInitializedAsync()
        {
            if (this.ServerAddress != null)
            {
                return;
            }

            int threadCount   = Environment.ProcessorCount;
            var executorGroup = new MultithreadEventLoopGroup(threadCount);
            var bufAllocator  = new PooledByteBufferAllocator(16 * 1024, 10 * 1024 * 1024 / threadCount); // reserve 10 MB for 64 KB buffers
            BlobSessionStatePersistenceProvider sessionStateProvider = await BlobSessionStatePersistenceProvider.CreateAsync(
                this.settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageConnectionString"),
                this.settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageContainerName"));

            TableQos2StatePersistenceProvider qos2StateProvider = await TableQos2StatePersistenceProvider.CreateAsync(
                this.settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageConnectionString"),
                this.settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageTableName"));

            var settings        = new Settings(this.settingsProvider);
            var authProvider    = new SasTokenDeviceIdentityProvider();
            var topicNameRouter = new ConfigurableMessageRouter();

            IotHubClientFactoryFunc iotHubClientFactoryMethod = IotHubClient.PreparePoolFactory(settings.IotHubConnectionString + ";DeviceId=stub", "a", 1);
            var iotHubFactory = new IotHubCommunicationFactory(iotHubClientFactoryMethod);

            ServerBootstrap server = new ServerBootstrap()
                                     .Group(executorGroup)
                                     .Channel <TcpServerSocketChannel>()
                                     .ChildOption(ChannelOption.Allocator, bufAllocator)
                                     .ChildOption(ChannelOption.AutoRead, false)
                                     .ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                ch.Pipeline.AddLast(TlsHandler.Server(this.tlsCertificate));
                ch.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, 256 * 1024),
                    new LoggingHandler(),
                    new MqttIotHubAdapter(
                        settings,
                        sessionStateProvider,
                        authProvider,
                        qos2StateProvider,
                        iotHubFactory,
                        topicNameRouter),
                    new XUnitLoggingHandler(this.output));
            }));

            IChannel serverChannel = await server.BindAsync(IPAddress.Any, this.ProtocolGatewayPort);

            this.ScheduleCleanup(async() =>
            {
                await serverChannel.CloseAsync();
                await executorGroup.ShutdownGracefullyAsync();
            });
            this.ServerAddress = IPAddress.Loopback;
        }
Exemplo n.º 4
0
        async Task RunAsync(CancellationToken cancellationToken)
        {
            var settingsProvider = new RoleEnvironmentSettingsProvider();

            var eventListener = new ObservableEventListener();

            eventListener.LogToWindowsAzureTable(RoleEnvironment.CurrentRoleInstance.Id, settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageConnectionString"), bufferingInterval: TimeSpan.FromMinutes(2));
            eventListener.EnableEvents(BootstrapperEventSource.Log, EventLevel.Informational);
            eventListener.EnableEvents(MqttIotHubAdapterEventSource.Log, EventLevel.Informational);
            eventListener.EnableEvents(DefaultEventSource.Log, EventLevel.Informational);

            int minWorkerThreads;
            int minCompletionPortThreads;

            ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);
            ThreadPool.SetMinThreads(minWorkerThreads, Math.Max(16, minCompletionPortThreads));

            int threadCount = Environment.ProcessorCount;

            BlobSessionStatePersistenceProvider blobSessionStateProvider =
                await BlobSessionStatePersistenceProvider.CreateAsync(
                    settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageConnectionString"),
                    settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageContainerName"));

            TableQos2StatePersistenceProvider tableQos2StateProvider =
                await TableQos2StatePersistenceProvider.CreateAsync(
                    settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageConnectionString"),
                    settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageTableName"));

            var bootstrapper = new Bootstrapper(
                settingsProvider,
                blobSessionStateProvider,
                tableQos2StateProvider);

            X509Certificate2 tlsCertificate = GetTlsCertificate(settingsProvider.GetSetting("TlsCertificateThumbprint"),
                                                                StoreName.My, StoreLocation.LocalMachine);

            try
            {
                await bootstrapper.RunAsync(tlsCertificate, threadCount, cancellationToken);
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.ToString());
                throw;
            }
            await bootstrapper.CloseCompletion;
        }
        /// <summary>
        /// Retrieves the session state provider to be used for MQTT Sessions
        /// </summary>
        /// <param name="traceId">A unique identifier used to correlate debugging and diagnostics messages</param>
        /// <param name="configuration">The gateway configuration</param>
        /// <returns>A session state persistence provider if available</returns>
        async Task <ISessionStatePersistenceProvider> GetSessionStateProviderAsync(Guid traceId, MqttServiceConfiguration configuration)
        {
            ISessionStatePersistenceProvider stateProvider = null;

            this.logger.Informational(traceId, this.componentName, "QOS state provider requested.");

            switch (configuration.MqttQoSStateProvider)
            {
            case MqttServiceConfiguration.QosStateType.AzureStorage:
                this.logger.Informational(traceId, this.componentName, "QOS state provider requested was Azure Storage.");
                var azureConfigurationProvider = new ConfigurationProvider <AzureSessionStateConfiguration>(traceId, this.serviceContext.ServiceName, this.serviceContext.CodePackageActivationContext, this.logger, "AzureState");

                azureConfigurationProvider.ConfigurationChangedEvent         += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();
                azureConfigurationProvider.ConfigurationPropertyChangedEvent += (sender, args) => this.unsupportedConfigurationChangeCallback?.Invoke();

                AzureSessionStateConfiguration azureConfiguration = azureConfigurationProvider.Config;

                if (azureConfiguration == null)
                {
                    this.logger.Critical(traceId, this.componentName, "QOS state provider or configuration could not be retrieved.");
                    throw new ApplicationException("Azure state QoS provider configuration could not be retrieved");
                }

                stateProvider = await BlobSessionStatePersistenceProvider.CreateAsync(azureConfiguration.BlobConnectionString, azureConfiguration.ContainerName).ConfigureAwait(false);

                this.logger.Informational(traceId, this.componentName, "QOS state provider request complete.");
                break;

            case MqttServiceConfiguration.QosStateType.ServiceFabricStateful:
                this.logger.Critical(traceId, this.componentName, "QOS state provider requested was Service Fabric Stateful Service but it is not currently implemented.");
                throw new NotImplementedException("Only azure storage provider is supported");

            default:
                this.logger.Critical(traceId, this.componentName, "QOS state provider requested was unknown.");
                throw new ApplicationException("MQTT state provider must be specified in configuration.");
            }


            return(stateProvider);
        }
Exemplo n.º 6
0
        static void BootstrapTcpServer()
        {
            int minWorkerThreads;
            int minCompletionPortThreads;

            ThreadPool.GetMinThreads(out minWorkerThreads, out minCompletionPortThreads);
            ThreadPool.SetMinThreads(minWorkerThreads, Math.Max(16, minCompletionPortThreads));

            int threadCount = Environment.ProcessorCount;

            try
            {
                var cts = new CancellationTokenSource();

                var certificate      = new X509Certificate2("protocol-gateway.contoso.com.pfx", "password");
                var settingsProvider = new AppConfigSettingsProvider();
                BlobSessionStatePersistenceProvider blobSessionStateProvider = BlobSessionStatePersistenceProvider.CreateAsync(
                    settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageConnectionString"),
                    settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageContainerName")).Result;


                var bootstrapper = new Bootstrapper(settingsProvider, blobSessionStateProvider);
                Task.Run(() => bootstrapper.RunAsync(certificate, threadCount, cts.Token, ValidateClientCertificate), cts.Token);

                while (true)
                {
                    string input = Console.ReadLine();
                    if (input != null && input.ToLowerInvariant() == "exit")
                    {
                        break;
                    }
                }

                cts.Cancel();
                bootstrapper.CloseCompletion.Wait(TimeSpan.FromSeconds(20));
            }
            catch (Exception ex)
            {
            }
        }
Exemplo n.º 7
0
        async Task EnsureServerInitializedAsync()
        {
            if (this.ServerAddress != null)
            {
                return;
            }

            int threadCount   = Environment.ProcessorCount;
            var executorGroup = new MultithreadEventLoopGroup(threadCount);
            BlobSessionStatePersistenceProvider sessionStateProvider = await BlobSessionStatePersistenceProvider.CreateAsync(
                this.settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageConnectionString"),
                this.settingsProvider.GetSetting("BlobSessionStatePersistenceProvider.StorageContainerName"));

            TableQos2StatePersistenceProvider qos2StateProvider = await TableQos2StatePersistenceProvider.CreateAsync(
                this.settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageConnectionString"),
                this.settingsProvider.GetSetting("TableQos2StatePersistenceProvider.StorageTableName"));

            var settings             = new Settings(this.settingsProvider);
            var iotHubClientSettings = new IotHubClientSettings(this.settingsProvider);
            var authProvider         = new SasTokenDeviceIdentityProvider();

            var telemetryProcessing = TopicHandling.CompileParserFromUriTemplates(new[] { "devices/{deviceId}/messages/events" });
            var commandProcessing   = TopicHandling.CompileFormatterFromUriTemplate("devices/{deviceId}/messages/devicebound/{subTopic=}");
            MessagingBridgeFactoryFunc bridgeFactory = IotHubBridge.PrepareFactory(iotHubClientSettings.IotHubConnectionString, 400, TimeSpan.FromMinutes(5),
                                                                                   iotHubClientSettings, bridge =>
            {
                bridge.RegisterRoute(topic => true, new TelemetrySender(bridge, telemetryProcessing));                                                        // handle all incoming messages with TelemetrySender
                bridge.RegisterSource(new CommandReceiver(bridge, PooledByteBufferAllocator.Default, commandProcessing));                                     // handle device command queue
                bridge.RegisterSource(new MethodHandler("command", bridge, (request, dispatcher) => DispatchCommands(bridge.DeviceId, request, dispatcher))); // register
            });

            ServerBootstrap server = new ServerBootstrap()
                                     .Group(executorGroup)
                                     .Channel <TcpServerSocketChannel>()
                                     .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
                                     .ChildOption(ChannelOption.AutoRead, false)
                                     .ChildHandler(new ActionChannelInitializer <IChannel>(ch =>
            {
                ch.Pipeline.AddLast(TlsHandler.Server(this.tlsCertificate));
                ch.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, 256 * 1024),
                    new LoggingHandler("SERVER"),
                    new MqttAdapter(
                        settings,
                        sessionStateProvider,
                        authProvider,
                        qos2StateProvider,
                        bridgeFactory),
                    new XUnitLoggingHandler(this.output));
            }));

            IChannel serverChannel = await server.BindAsync(IPAddress.Any, this.ProtocolGatewayPort);

            this.ScheduleCleanup(async() =>
            {
                await serverChannel.CloseAsync();
                await executorGroup.ShutdownGracefullyAsync();
            });
            this.ServerAddress = IPAddress.Loopback;
        }