Esempio n. 1
0
        public async Task ProcessWebSocketRequestAsync(WebSocket webSocket,
                                                       Option <EndPoint> localEndPoint,
                                                       EndPoint remoteEndPoint,
                                                       string correlationId,
                                                       Option <X509Certificate2> clientCert,
                                                       Option <IList <X509Certificate2> > clientCertChain)
        {
            try
            {
                DeviceIdentityProvider identityProvider = new DeviceIdentityProvider(this.authenticator, this.clientCredentialsFactory, true);
                var serverChannel = new ServerWebSocketChannel(
                    webSocket,
                    remoteEndPoint
                    );

                clientCert.Map(cert =>
                {
                    return(identityProvider.RemoteCertificateValidationCallback(cert, clientCertChain.Expect(() => new ArgumentException("Certificate chain was found to be null"))));
                });

                serverChannel
                .Option(ChannelOption.Allocator, this.byteBufferAllocator)
                .Option(ChannelOption.AutoRead, this.autoRead)
                .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
                .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
                .Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, this.mqttDecoderMaxMessageSize),
                    new MqttAdapter(
                        this.settings,
                        this.sessionProviderFactory(),
                        identityProvider,
                        null,
                        this.messagingBridgeFactoryFunc));

                await this.workerGroup.GetNext().RegisterAsync(serverChannel);

                Events.Established(correlationId);

                await serverChannel.WebSocketClosed.Task;  // This will wait until the websocket is closed
            }
            catch (Exception ex) when(!ex.IsFatal())
            {
                Events.Exception(correlationId, ex);
                throw;
            }
        }
Esempio n. 2
0
        ServerBootstrap SetupServerBootstrap()
        {
            int maxInboundMessageSize = this.settingsProvider.GetIntegerSetting("MaxInboundMessageSize", DefaultMaxInboundMessageSize);
            int threadCount           = this.settingsProvider.GetIntegerSetting("ThreadCount", DefaultThreadCount);
            int listenBacklogSize     = this.settingsProvider.GetIntegerSetting("ListenBacklogSize", DefaultListenBacklogSize);
            int parentEventLoopCount  = this.settingsProvider.GetIntegerSetting("EventLoopCount", DefaultParentEventLoopCount);
            var settings = new Settings(this.settingsProvider);

            MessagingBridgeFactoryFunc bridgeFactory = this.mqttConnectionProvider.Connect;

            var bootstrap = new ServerBootstrap();
            // multithreaded event loop that handles the incoming connection
            IEventLoopGroup parentEventLoopGroup = new MultithreadEventLoopGroup(parentEventLoopCount);

            // multithreaded event loop (worker) that handles the traffic of the accepted connections
            this.eventLoopGroup = new MultithreadEventLoopGroup(threadCount);

            bootstrap.Group(parentEventLoopGroup, this.eventLoopGroup)
            .Option(ChannelOption.SoBacklog, listenBacklogSize)
            // Allow listening socket to force bind to port if previous socket is still in TIME_WAIT
            // Fixes "address is already in use" errors
            .Option(ChannelOption.SoReuseaddr, true)
            .ChildOption(ChannelOption.Allocator, this.byteBufferAllocator)
            .ChildOption(ChannelOption.AutoRead, AutoRead)
            // channel that accepts incoming connections
            .Channel <TcpServerSocketChannel>()
            // Channel initializer, it is handler that is purposed to help configure a new channel
            .ChildHandler(new ActionChannelInitializer <ISocketChannel>(channel =>
            {
                DeviceIdentityProvider identityProvider = new DeviceIdentityProvider(this.authenticator, this.clientCredentialsFactory, this.clientCertAuthAllowed);
                // configure the channel pipeline of the new Channel by adding handlers
                TlsSettings serverSettings = new ServerTlsSettings(
                    certificate: this.tlsCertificate,
                    negotiateClientCertificate: this.clientCertAuthAllowed
                    );

                channel.Pipeline.AddLast(new TlsHandler(stream =>
                                                        new SslStream(stream,
                                                                      true,
                                                                      (sender, remoteCertificate, remoteChain, sslPolicyErrors) =>
                                                                      this.clientCertAuthAllowed ?
                                                                      identityProvider.RemoteCertificateValidationCallback(remoteCertificate, remoteChain) : true),
                                                        serverSettings));

                channel.Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(true, maxInboundMessageSize),
                    new MqttAdapter(
                        settings,
                        this.sessionProvider,
                        identityProvider,
                        null,
                        bridgeFactory));
            }));

            var mqttWebSocketListener = new MqttWebSocketListener(
                settings,
                bridgeFactory,
                this.authenticator,
                this.clientCredentialsFactory,
                () => this.sessionProvider,
                new MultithreadEventLoopGroup(Environment.ProcessorCount),
                this.byteBufferAllocator,
                AutoRead,
                maxInboundMessageSize);

            this.webSocketListenerRegistry.TryRegister(mqttWebSocketListener);

            return(bootstrap);
        }