Exemplo n.º 1
0
        public async Task PublishAsync(string topic, byte[] payload, QualityOfService qos = QualityOfService.AtMostOnce, bool retain = false)
        {
            TaskCompletionSource <object> future = new TaskCompletionSource <object>();
            PublishPacket packet = new PublishPacket(qos, false, retain);

            packet.TopicName = topic;
            packet.PacketId  = PacketIdProvider.NewPacketId();
            packet.Payload   = Unpooled.WrappedBuffer(payload);
            packet.Retain();
            WriteResult result = await sendAndFlushAsync(packet);

            if (!result.Success)
            {
                packet.Release();//needed?
                future.SetException(result.Exception);
            }
            else if (qos == QualityOfService.AtLeastOnce)
            {
                packet.Release();       //needed?
                future.SetResult(null); //We don't get an ACK for QOS 0
            }
            else
            {
                PendingPublish pendingPublish = new PendingPublish(packet, future);//return after PubAct(QoS=1)/PubRel(QoS=2) received.
                pendingPublishes.TryAdd(packet.PacketId, pendingPublish);
                pendingPublish.RetransmitPublish(eventLoopGroup.GetNext(), sendAndFlushAsync);
            }
            await future.Task;
        }
Exemplo n.º 2
0
            public override void ChannelActive(IChannelHandlerContext ctx)
            {
                IEventLoop loop = _group.GetNext();

                if (_sameEventLoop)
                {
                    Deregister(ctx, loop);
                }
                else
                {
                    loop.Execute(() => Deregister(ctx, loop));
                }
            }
Exemplo n.º 3
0
            public override void ChannelRead(IChannelHandlerContext ctx, object msg)
            {
                var child = (IChannel)msg;

                child.Pipeline.AddLast(childHandler);

                if (childOptionsSetupFunc != null)
                {
                    if (!childOptionsSetupFunc(child.Configuration))
                    {
                        Logger.Warning("Not all configuration options could be set.");
                    }
                }

                // todo: async/await instead?
                try
                {
                    childGroup.GetNext()
                    .RegisterAsync(child)
                    .ContinueWith(future => ForceClose(child, future.Exception),
                                  TaskContinuationOptions.NotOnRanToCompletion | TaskContinuationOptions.ExecuteSynchronously);
                }
                catch (Exception ex)
                {
                    ForceClose(child, ex);
                }
            }
Exemplo n.º 4
0
        public async Task TestReleaseAfterClosePool()
        {
            var addr = new LocalAddress(ChannelPoolTestUtils.GetLocalAddrId());
            Bootstrap cb = new Bootstrap().RemoteAddress(addr).Group(_group).Channel<LocalChannel>();

            ServerBootstrap sb = new ServerBootstrap()
                .Group(_group)
                .Channel<LocalServerChannel>()
                .ChildHandler(
                    new ActionChannelInitializer<LocalChannel>(
                        ch => ch.Pipeline.AddLast(new ChannelHandlerAdapter()))
                );

            // Start server
            IChannel sc = await sb.BindAsync(addr);

            var pool = new FixedChannelPool(cb, new TestChannelPoolHandler(), 2);
            IChannel channel = await pool.AcquireAsync();
            pool.Close();

            await _group.GetNext().SubmitAsync(() => TaskUtil.Completed);
            var e = await Assert.ThrowsAsync<InvalidOperationException>(async () => await pool.ReleaseAsync(channel));
            Assert.Same(FixedChannelPool.PoolClosedOnReleaseException, e);

            // Since the pool is closed, the Channel should have been closed as well.
            await channel.CloseCompletion;
            Assert.False(channel.IsOpen, "Unexpected open channel");
            await sc.CloseAsync();
            pool.Close();
        }
Exemplo n.º 5
0
        Func <IPAddress, int, Task <IChannel> > CreateWebSocketChannelFactory(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings)
        {
            return(async(address, port) =>
            {
                IEventLoopGroup eventLoopGroup = EventLoopGroupPool.TakeOrAdd(this.eventLoopGroupKey);

                var websocketUri = new Uri(WebSocketConstants.Scheme + iotHubConnectionString.HostName + ":" + WebSocketConstants.SecurePort + WebSocketConstants.UriSuffix);
                var websocket = new ClientWebSocket();
                websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Mqtt);

                // Check if we're configured to use a proxy server
                IWebProxy webProxy = WebRequest.DefaultWebProxy;
                Uri proxyAddress = webProxy?.GetProxy(websocketUri);
                if (!websocketUri.Equals(proxyAddress))
                {
                    // Configure proxy server
                    websocket.Options.Proxy = webProxy;
                }

                if (settings.ClientCertificate != null)
                {
                    websocket.Options.ClientCertificates.Add(settings.ClientCertificate);
                }
                else
                {
                    websocket.Options.UseDefaultCredentials = true;
                }

                using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                {
                    await websocket.ConnectAsync(websocketUri, cancellationTokenSource.Token);
                }

                var clientChannel = new ClientWebSocketChannel(null, websocket);
                clientChannel
                .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
                .Option(ChannelOption.AutoRead, false)
                .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
                .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
                .Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(false, MaxMessageSize),
                    this.mqttIotHubAdapterFactory.Create(this.OnConnected, this.OnMessageReceived, this.OnError, iotHubConnectionString, settings));
                await eventLoopGroup.GetNext().RegisterAsync(clientChannel);

                this.ScheduleCleanup(() =>
                {
                    EventLoopGroupPool.Release(this.eventLoopGroupKey);
                    return TaskConstants.Completed;
                });

                return clientChannel;
            });
        }
Exemplo n.º 6
0
 /// <summary>
 /// If running in a context of an existing <see cref="IEventLoop"/>, this <see cref="IEventLoop"/> is returned.
 /// Otherwise, <see cref="IEventLoop"/> is retrieved from underlying <see cref="IEventLoopGroup"/>.
 /// </summary>
 public override IEventExecutor GetNext()
 {
     if (ExecutionEnvironment.TryGetCurrentExecutor(out var executor))
     {
         if (executor is IEventLoop loop && loop.Parent == _innerGroup)
         {
             return(loop);
         }
     }
     return(_innerGroup.GetNext());
 }
Exemplo n.º 7
0
        public async Task TestBindDeadLock()
        {
            Bootstrap bootstrapA = new Bootstrap();

            bootstrapA.Group(_groupA);
            bootstrapA.Channel <LocalChannel>();
            bootstrapA.Handler(_dummyHandler);

            Bootstrap bootstrapB = new Bootstrap();

            bootstrapB.Group(_groupB);
            bootstrapB.Channel <LocalChannel>();
            bootstrapB.Handler(_dummyHandler);

            var bindFutures = new List <Task <int> >();

            // Try to bind from each other.
            for (int i = 0; i < 1024; i++)
            {
                bindFutures.Add(_groupA.GetNext().SubmitAsync(() =>
                {
                    bootstrapB.BindAsync(LocalAddress.Any);
                    return(i);
                }));
                bindFutures.Add(_groupB.GetNext().SubmitAsync(() =>
                {
                    bootstrapA.BindAsync(LocalAddress.Any);
                    return(i);
                }));
            }

            for (int i = 0; i < bindFutures.Count; i++)
            {
                Task <int> result = bindFutures[i];
                await      result;
            }
        }
        Func <IPAddress, int, Task <IChannel> > CreateWebSocketChannelFactory(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings)
        {
            return(async(address, port) =>
            {
                string additionalQueryParams = "";
#if WINDOWS_UWP || NETSTANDARD1_3
                // UWP and NETSTANDARD1_3 implementation doesn't set client certs, so we want to tell the IoT Hub to not ask for them
                additionalQueryParams = "?iothub-no-client-cert=true";
#endif
                IEventLoopGroup eventLoopGroup = EventLoopGroupPool.TakeOrAdd(this.eventLoopGroupKey);

                var websocketUri = new Uri(WebSocketConstants.Scheme + iotHubConnectionString.HostName + ":" + WebSocketConstants.SecurePort + WebSocketConstants.UriSuffix + additionalQueryParams);
                var websocket = new ClientWebSocket();
                websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Mqtt);

#if !WINDOWS_UWP // UWP does not support proxies
                // Check if we're configured to use a proxy server
                IWebProxy webProxy = WebRequest.DefaultWebProxy;
                Uri proxyAddress = null;
#if !NETSTANDARD1_3
                proxyAddress = webProxy?.GetProxy(websocketUri);
#endif
                if (!websocketUri.Equals(proxyAddress))
                {
                    // Configure proxy server
                    websocket.Options.Proxy = webProxy;
                }
#endif

                if (settings.ClientCertificate != null)
                {
                    websocket.Options.ClientCertificates.Add(settings.ClientCertificate);
                }
#if !WINDOWS_UWP && !NETSTANDARD1_3 // UseDefaultCredentials is not in UWP and NetStandard
                else
                {
                    websocket.Options.UseDefaultCredentials = true;
                }
#endif

                using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                {
                    await websocket.ConnectAsync(websocketUri, cancellationTokenSource.Token);
                }

#if WINDOWS_UWP
                PlatformProvider.Platform = new UWPPlatform();
#endif
                var clientChannel = new ClientWebSocketChannel(null, websocket);
                clientChannel
                .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
                .Option(ChannelOption.AutoRead, false)
                .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
                .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
                .Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(false, MaxMessageSize),
                    this.mqttIotHubAdapterFactory.Create(this, iotHubConnectionString, settings));
                await eventLoopGroup.GetNext().RegisterAsync(clientChannel);

                this.ScheduleCleanup(() =>
                {
                    EventLoopGroupPool.Release(this.eventLoopGroupKey);
                    return TaskConstants.Completed;
                });

                return clientChannel;
            });
        }
        Func <IPAddress[], int, Task <IChannel> > CreateWebSocketChannelFactory(IotHubConnectionString iotHubConnectionString, MqttTransportSettings settings, ProductInfo productInfo)
        {
            return(async(address, port) =>
            {
                string additionalQueryParams = "";
#if NETSTANDARD1_3
                // NETSTANDARD1_3 implementation doesn't set client certs, so we want to tell the IoT Hub to not ask for them
                additionalQueryParams = "?iothub-no-client-cert=true";
#endif
                IEventLoopGroup eventLoopGroup = EventLoopGroupPool.TakeOrAdd(this.eventLoopGroupKey);

                var websocketUri = new Uri(WebSocketConstants.Scheme + iotHubConnectionString.HostName + ":" + WebSocketConstants.SecurePort + WebSocketConstants.UriSuffix + additionalQueryParams);
                var websocket = new ClientWebSocket();
                websocket.Options.AddSubProtocol(WebSocketConstants.SubProtocols.Mqtt);

                // Check if we're configured to use a proxy server
                IWebProxy webProxy = settings.Proxy;

                try
                {
                    if (webProxy != DefaultWebProxySettings.Instance)
                    {
                        // Configure proxy server
                        websocket.Options.Proxy = webProxy;
                        if (Logging.IsEnabled)
                        {
                            Logging.Info(this, $"{nameof(CreateWebSocketChannelFactory)} Setting ClientWebSocket.Options.Proxy");
                        }
                    }
                }
                catch (PlatformNotSupportedException)
                {
                    // .NET Core 2.0 doesn't support proxy. Ignore this setting.
                    if (Logging.IsEnabled)
                    {
                        Logging.Error(this, $"{nameof(CreateWebSocketChannelFactory)} PlatformNotSupportedException thrown as .NET Core 2.0 doesn't support proxy");
                    }
                }

                if (settings.ClientCertificate != null)
                {
                    websocket.Options.ClientCertificates.Add(settings.ClientCertificate);
                }

                using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(1)))
                {
                    await websocket.ConnectAsync(websocketUri, cancellationTokenSource.Token).ConfigureAwait(false);
                }

                var clientChannel = new ClientWebSocketChannel(null, websocket);
                clientChannel
                .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default)
                .Option(ChannelOption.AutoRead, false)
                .Option(ChannelOption.RcvbufAllocator, new AdaptiveRecvByteBufAllocator())
                .Option(ChannelOption.MessageSizeEstimator, DefaultMessageSizeEstimator.Default)
                .Pipeline.AddLast(
                    MqttEncoder.Instance,
                    new MqttDecoder(false, MaxMessageSize),
                    this.mqttIotHubAdapterFactory.Create(this, iotHubConnectionString, settings, productInfo));
                await eventLoopGroup.GetNext().RegisterAsync(clientChannel).ConfigureAwait(false);

                this.ScheduleCleanup(() =>
                {
                    EventLoopGroupPool.Release(this.eventLoopGroupKey);
                    return TaskConstants.Completed;
                });

                return clientChannel;
            });
        }