ServerBootstrap SetupBootstrap(ChannelHandlerAdapter firstHandler)
        {
            Contract.Requires(firstHandler != null);

            return(new ServerBootstrap()
                   .Group(this.parentEventLoopGroup, this.eventLoopGroup)
                   .Option(ChannelOption.SoBacklog, ListenBacklogSize)
                   .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
                   .Channel <TcpServerSocketChannel>()
                   .ChildHandler(new ActionChannelInitializer <IChannel>(channel =>
            {
                int connectionPoolSize = this.settingsProvider.GetIntegerSetting("IotHubClient.ConnectionPoolSize", DefaultConnectionPoolSize);
                TimeSpan connectionIdleTimeout = this.settingsProvider.GetTimeSpanSetting("IotHubClient.ConnectionIdleTimeout", DefaultConnectionIdleTimeout);
                string connectionString = this.iotHubClientSettings.IotHubConnectionString;
                int maxInboundMessageSize = this.settingsProvider.GetIntegerSetting("MaxInboundMessageSize", 256 * 1024);

                var messagingAddressConverter = new IoTHubProvider.Addressing.MessageAddressConverter();
                Func <IDeviceIdentity, Task <ITcpIoTHubMessagingServiceClient> > deviceClientFactory
                    = IotHubClient.PreparePoolFactory(connectionString, connectionPoolSize, connectionIdleTimeout, this.iotHubClientSettings);

                MessagingBridgeFactoryFunc bridgeFactory
                    = async deviceIdentity => new SingleClientMessagingBridge(deviceIdentity, await deviceClientFactory(deviceIdentity));

                channel.Pipeline.AddLast(firstHandler);
                channel.Pipeline.AddLast(DeviceTopicDecoder.HandlerName, new DeviceTopicDecoder(this.credentialProvider, messagingAddressConverter.TopicTemplates));
                channel.Pipeline.AddLast(SocketIoTHubAdapter.HandlerName, new SocketIoTHubAdapter(this.settings, credentialProvider, this.authProvider, bridgeFactory));
            })));
        }
        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;
        }
Example #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;
        }
        ServerBootstrap SetupBootstrap()
        {
            int maxInboundMessageSize = this.settingsProvider.GetIntegerSetting("MaxInboundMessageSize", 256 * 1024);
            int connectionPoolSize;

            if (!this.settingsProvider.TryGetIntegerSetting("IotHubClient.ConnectionPoolSize", out connectionPoolSize))
            {
                connectionPoolSize = DefaultConnectionPoolSize;
            }

            TimeSpan connectionIdleTimeout;

            if (!this.settingsProvider.TryGetTimeSpanSetting("IotHubClient.ConnectionIdleTimeout", out connectionIdleTimeout))
            {
                connectionIdleTimeout = DefaultConnectionIdleTimeout;
            }

            string connectionString = this.settings.IotHubConnectionString;

            if (connectionString.IndexOf("DeviceId=", StringComparison.OrdinalIgnoreCase) == -1)
            {
                connectionString += ";DeviceId=stub";
            }

            var deviceClientFactory = new ThreadLocal <IotHubClientFactoryFunc>(() =>
            {
                string poolId = Guid.NewGuid().ToString("N");
                return(IotHubClient.PreparePoolFactory(connectionString, poolId, connectionPoolSize, connectionIdleTimeout));
            });

            var iotHubCommunicationFactory = new IotHubCommunicationFactory(deviceClientFactory.Value);

            return(new ServerBootstrap()
                   .Group(this.parentEventLoopGroup, this.eventLoopGroup)
                   .Option(ChannelOption.SoBacklog, ListenBacklogSize)
                   .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
                   .ChildOption(ChannelOption.AutoRead, false)
                   .Channel <TcpServerSocketChannel>()
                   .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel =>
            {
                channel.Pipeline.AddLast(TlsHandler.Server(this.tlsCertificate));
                channel.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, maxInboundMessageSize),
                    new MqttIotHubAdapter(
                        this.settings,
                        this.sessionStateManager,
                        this.authProvider,
                        this.qos2StateProvider,
                        iotHubCommunicationFactory,
                        this.iotHubMessageRouter));
            })));
        }
        ServerBootstrap SetupBootstrap()
        {
            if (this.settings.DeviceReceiveAckCanTimeout && this.iotHubClientSettings.MaxPendingOutboundMessages > 1)
            {
                throw new InvalidOperationException("Cannot maintain ordering on retransmission with more than 1 allowed pending outbound message.");
            }

            int      maxInboundMessageSize = this.settingsProvider.GetIntegerSetting("MaxInboundMessageSize", 256 * 1024);
            int      connectionPoolSize    = this.settingsProvider.GetIntegerSetting("IotHubClient.ConnectionPoolSize", DefaultConnectionPoolSize);
            TimeSpan connectionIdleTimeout = this.settingsProvider.GetTimeSpanSetting("IotHubClient.ConnectionIdleTimeout", DefaultConnectionIdleTimeout);
            string   connectionString      = this.iotHubClientSettings.IotHubConnectionString;

            Func <IDeviceIdentity, Task <IMessagingServiceClient> > deviceClientFactory = IotHubClient.PreparePoolFactory(connectionString, connectionPoolSize,
                                                                                                                          connectionIdleTimeout, this.iotHubClientSettings, PooledByteBufferAllocator.Default, this.topicNameConverter);
            MessagingBridgeFactoryFunc bridgeFactory = async deviceIdentity => new SingleClientMessagingBridge(deviceIdentity, await deviceClientFactory(deviceIdentity));

            return(new ServerBootstrap()
                   .Group(this.parentEventLoopGroup, this.eventLoopGroup)
                   .Option(ChannelOption.SoBacklog, ListenBacklogSize)
                   .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
                   .ChildOption(ChannelOption.AutoRead, false)
                   .Channel <TcpServerSocketChannel>()
                   .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel =>
            {
                channel.Pipeline.AddLast(TlsHandler.Server(this.tlsCertificate));
                channel.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, maxInboundMessageSize),
                    new MqttAdapter(
                        this.settings,
                        this.sessionStateManager,
                        this.authProvider,
                        this.qos2StateProvider,
                        bridgeFactory));
            })));
        }