public MqttAdapter( Settings settings, ISessionStatePersistenceProvider sessionStateManager, IDeviceIdentityProvider authProvider, IQos2StatePersistenceProvider qos2StateProvider, MqttBridgeFactoryFunc messagingBridgeFactory) { Contract.Requires(settings != null); Contract.Requires(sessionStateManager != null); Contract.Requires(authProvider != null); Contract.Requires(messagingBridgeFactory != null); if (qos2StateProvider != null) { this.maxSupportedQosToClient = QualityOfService.ExactlyOnce; this.qos2StateProvider = qos2StateProvider; } else { this.maxSupportedQosToClient = QualityOfService.AtLeastOnce; } this.settings = settings; this.sessionStateManager = sessionStateManager; this.authProvider = authProvider; this.messagingBridgeFactory = messagingBridgeFactory; }
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); MqttBridgeFactoryFunc bridgeFactory = async identity => new SingleClientMqttMessagingBridge(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; }
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); MqttBridgeFactoryFunc bridgeFactory = async deviceIdentity => new SingleClientMqttMessagingBridge(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)); }))); }