ServerBootstrap SetupBootstrap()
        {
            // pull/customize configuration
            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;

            // setup message processing logic
            var telemetryProcessing = TopicHandling.CompileParserFromUriTemplates(new[] { "devices/{deviceId}/messages/events" });
            var commandProcessing   = TopicHandling.CompileFormatterFromUriTemplate("devices/{deviceId}/messages/devicebound");
            MessagingBridgeFactoryFunc bridgeFactory = IotHubBridge.PrepareFactory(connectionString, connectionPoolSize,
                                                                                   connectionIdleTimeout, this.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("SendMessageToDevice", bridge, (request, dispatcher) => DispatchCommands(bridge.DeviceId, request, dispatcher))); // register
            });

            var acceptLimiter = new AcceptLimiter(MaxConcurrentAccepts);

            return(new ServerBootstrap()
                   .Group(this.parentEventLoopGroup, this.eventLoopGroup)
                   .Option(ChannelOption.SoBacklog, ListenBacklogSize)
                   .Option(ChannelOption.AutoRead, false)
                   .ChildOption(ChannelOption.Allocator, PooledByteBufferAllocator.Default)
                   .ChildOption(ChannelOption.AutoRead, false)
                   .Channel <TcpServerSocketChannel>()
                   .Handler(acceptLimiter)
                   .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel =>
            {
                channel.Pipeline.AddLast(
                    TlsHandler.Server(this.tlsCertificate),
                    new AcceptLimiterTlsReleaseHandler(acceptLimiter),
                    MqttEncoder.Instance,
                    new MqttDecoder(true, maxInboundMessageSize),
                    new MqttAdapter(
                        this.settings,
                        this.sessionStateManager,
                        this.authProvider,
                        this.qos2StateProvider,
                        bridgeFactory));
            })));
        }
예제 #2
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;
        }