static async Task RunServerAsync() { Console.WriteLine("Gateway Start, ThreadName=" + System.Threading.Thread.CurrentThread.ManagedThreadId); var bossGroup = new MultithreadEventLoopGroup(1); var workerGroup = new MultithreadEventLoopGroup(); try { var bootstrap = new ServerBootstrap(); bootstrap .Group(bossGroup, workerGroup) .Channel<TcpServerSocketChannel>() .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler(LogLevel.INFO)) .ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LengthFieldPrepender(2)); pipeline.AddLast(new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); pipeline.AddLast(new GatewayHandler()); })); IChannel bootstrapChannel = await bootstrap.BindAsync(GatewaySettings.Port); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { Task.WaitAll(bossGroup.ShutdownGracefullyAsync(), workerGroup.ShutdownGracefullyAsync()); } }
static async Task RunClientAsync() { var eventListener = new ObservableEventListener(); eventListener.LogToConsole(); eventListener.EnableEvents(DefaultEventSource.Log, EventLevel.Verbose); var group = new MultithreadEventLoopGroup(); X509Certificate2 cert = null; string targetHost = null; if (EchoClientSettings.IsSsl) { cert = new X509Certificate2("dotnetty.com.pfx", "password"); targetHost = cert.GetNameInfo(X509NameType.DnsName, false); } try { var bootstrap = new Bootstrap(); bootstrap .Group(group) .Channel<TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer<ISocketChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (cert != null) { pipeline.AddLast(new TlsHandler(stream => new SslStream(stream, true, (sender, certificate, chain, errors) => true), new ClientTlsSettings(targetHost))); } pipeline.AddLast(new LengthFieldPrepender(2)); pipeline.AddLast(new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); pipeline.AddLast(new EchoClientHandler()); })); IChannel bootstrapChannel = await bootstrap.ConnectAsync(new IPEndPoint(EchoClientSettings.Host, EchoClientSettings.Port)); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { group.ShutdownGracefullyAsync().Wait(1000); eventListener.Dispose(); } }
static async Task RunServerAsync() { var eventListener = new ObservableEventListener(); eventListener.LogToConsole(); eventListener.EnableEvents(DefaultEventSource.Log, EventLevel.Verbose); var bossGroup = new MultithreadEventLoopGroup(1); var workerGroup = new MultithreadEventLoopGroup(); X509Certificate2 tlsCertificate = null; if (EchoServerSettings.IsSsl) { tlsCertificate = new X509Certificate2("dotnetty.com.pfx", "password"); } try { var bootstrap = new ServerBootstrap(); bootstrap .Group(bossGroup, workerGroup) .Channel<TcpServerSocketChannel>() .Option(ChannelOption.SoBacklog, 100) .Handler(new LoggingHandler(LogLevel.INFO)) .ChildHandler(new ActionChannelInitializer<ISocketChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; if (tlsCertificate != null) { pipeline.AddLast(TlsHandler.Server(tlsCertificate)); } pipeline.AddLast(new LengthFieldPrepender(2)); pipeline.AddLast(new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); pipeline.AddLast(new EchoServerHandler()); })); IChannel bootstrapChannel = await bootstrap.BindAsync(EchoServerSettings.Port); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { Task.WaitAll(bossGroup.ShutdownGracefullyAsync(), workerGroup.ShutdownGracefullyAsync()); eventListener.Dispose(); } }
public async void EchoServerAndClient() { var testPromise = new TaskCompletionSource(); var tlsCertificate = new X509Certificate2("dotnetty.com.pfx", "password"); Func<Task> closeServerFunc = await this.StartServerAsync(true, ch => { ch.Pipeline.AddLast(TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast(new EchoChannelHandler()); }, testPromise); var group = new MultithreadEventLoopGroup(); Bootstrap b = new Bootstrap() .Group(group) .Channel<TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer<ISocketChannel>(ch => { ch.Pipeline.AddLast(TlsHandler.Client("dotnetty.com", null, (sender, certificate, chain, errors) => true)); ch.Pipeline.AddLast(new TestScenarioRunner(this.GetEchoClientScenario, testPromise)); })); this.output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.output.WriteLine("Connected channel: {0}", clientChannel); await Task.WhenAny(testPromise.Task, Task.Delay(TimeSpan.FromMinutes(1))); Assert.True(testPromise.Task.IsCompleted); } finally { Task serverCloseTask = closeServerFunc(); if (clientChannel != null) { clientChannel.CloseAsync().Wait(TimeSpan.FromSeconds(5)); } if (!Task.WaitAll(new[] { serverCloseTask, group.ShutdownGracefullyAsync() }, ShutdownTimeout)) { this.output.WriteLine("Loops didn't stop in time."); } } }
static async Task RunClientAsync() { IPAddress host = IPAddress.Parse("192.168.0.10"); int port = 5882; var factory = new ClientSessionFactory(); var group = new MultithreadEventLoopGroup(); try { var bootstrap = new Bootstrap(); bootstrap .Group(group) .Channel<TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer<ISocketChannel>(channel => { IChannelPipeline pipeline = channel.Pipeline; pipeline.AddLast(new LengthFieldPrepender( ByteOrder.LittleEndian, 2, 0, false)); pipeline.AddLast(new LengthFieldBasedFrameDecoder( ByteOrder.LittleEndian, ushort.MaxValue, 0, 2, 0, 2, true)); pipeline.AddLast(new ClientHandler(factory)); })); IChannel bootstrapChannel = await bootstrap.ConnectAsync(new IPEndPoint(host, port)); Console.ReadLine(); await bootstrapChannel.CloseAsync(); } finally { group.ShutdownGracefullyAsync().Wait(1000); } }
/// <summary> /// Starts Echo server. /// </summary> /// <returns>function to trigger closure of the server.</returns> async Task<Func<Task>> StartServerAsync(bool tcpNoDelay, Action<IChannel> childHandlerSetupAction, TaskCompletionSource testPromise) { var bossGroup = new MultithreadEventLoopGroup(1); var workerGroup = new MultithreadEventLoopGroup(); bool started = false; //var tlsCertificate = new X509Certificate2("dotnetty.com.pfx", "password"); try { ServerBootstrap b = new ServerBootstrap() .Group(bossGroup, workerGroup) .Channel<TcpServerSocketChannel>() .Handler(new ExceptionCatchHandler(ex => testPromise.TrySetException(ex))) .ChildHandler(new ActionChannelInitializer<ISocketChannel>(childHandlerSetupAction)) .ChildOption(ChannelOption.TcpNodelay, tcpNoDelay); this.output.WriteLine("Configured ServerBootstrap: {0}", b); IChannel serverChannel = await b.BindAsync(Port); this.output.WriteLine("Bound server channel: {0}", serverChannel); started = true; return async () => { try { await serverChannel.CloseAsync(); } finally { Task.WaitAll(bossGroup.ShutdownGracefullyAsync(), workerGroup.ShutdownGracefullyAsync()); } }; } finally { if (!started) { Task.WaitAll(bossGroup.ShutdownGracefullyAsync(), workerGroup.ShutdownGracefullyAsync()); } } }
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 SasTokenAuthenticationProvider(); var topicNameRouter = new TopicNameRouter(); DeviceClientFactoryFunc deviceClientFactoryFactory = IotHubDeviceClient.PreparePoolFactory(settings.IotHubConnectionString + ";DeviceId=stub", "a", 1); 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 MqttIotHubAdapter( settings, deviceClientFactoryFactory, sessionStateProvider, authProvider, topicNameRouter, qos2StateProvider), 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; }
public async Task BasicFunctionalityTest() { await this.EnsureServerInitializedAsync(); int protocolGatewayPort = this.ProtocolGatewayPort; string iotHubConnectionString = ConfigurationManager.AppSettings["IoTHubConnectionString"]; IotHubConnectionStringBuilder hubConnectionStringBuilder = IotHubConnectionStringBuilder.Create(iotHubConnectionString); bool deviceNameProvided; this.deviceId = ConfigurationManager.AppSettings["End2End.DeviceName"]; if (!string.IsNullOrEmpty(this.deviceId)) { deviceNameProvided = true; } else { deviceNameProvided = false; this.deviceId = Guid.NewGuid().ToString("N"); } RegistryManager registryManager = RegistryManager.CreateFromConnectionString(iotHubConnectionString); if (!deviceNameProvided) { await registryManager.AddDeviceAsync(new Device(this.deviceId)); this.ScheduleCleanup(async () => { await registryManager.RemoveDeviceAsync(this.deviceId); await registryManager.CloseAsync(); }); } Device device = await registryManager.GetDeviceAsync(this.deviceId); this.deviceSas = new SharedAccessSignatureBuilder { Key = device.Authentication.SymmetricKey.PrimaryKey, Target = string.Format("{0}/devices/{1}", hubConnectionStringBuilder.HostName, this.deviceId), KeyName = null, TimeToLive = TimeSpan.FromMinutes(20) } .ToSignature(); EventHubClient eventHubClient = EventHubClient.CreateFromConnectionString(iotHubConnectionString, "messages/events"); EventHubConsumerGroup ehGroup = eventHubClient.GetDefaultConsumerGroup(); string[] partitionIds = (await eventHubClient.GetRuntimeInformationAsync()).PartitionIds; EventHubReceiver[] receivers = await Task.WhenAll(partitionIds.Select(pid => ehGroup.CreateReceiverAsync(pid.Trim(), DateTime.UtcNow))); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(iotHubConnectionString); Stopwatch sw = Stopwatch.StartNew(); var testPromise = new TaskCompletionSource(); var group = new MultithreadEventLoopGroup(); string targetHost = this.tlsCertificate.GetNameInfo(X509NameType.DnsName, false); Bootstrap bootstrap = new Bootstrap() .Group(group) .Channel<TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer<ISocketChannel>(ch => ch.Pipeline.AddLast( TlsHandler.Client(targetHost, null, (sender, certificate, chain, errors) => true), MqttEncoder.Instance, new MqttDecoder(false, 256 * 1024), new TestScenarioRunner(cmf => GetClientScenario(cmf, hubConnectionStringBuilder.HostName, this.deviceId, this.deviceSas), testPromise, CommunicationTimeout, CommunicationTimeout), new XUnitLoggingHandler(this.output)))); IChannel clientChannel = await bootstrap.ConnectAsync(this.ServerAddress, protocolGatewayPort); this.ScheduleCleanup(async () => { await clientChannel.CloseAsync(); await group.ShutdownGracefullyAsync(); }); Task testWorkTask = Task.Run(async () => { Tuple<EventData, string>[] ehMessages = await CollectEventHubMessagesAsync(receivers, 2); Tuple<EventData, string> qos0Event = Assert.Single(ehMessages.Where(x => TelemetryQoS0Content.Equals(x.Item2, StringComparison.Ordinal))); //Assert.Equal((string)qos0Event.Item1.Properties["level"], "verbose"); //Assert.Equal((string)qos0Event.Item1.Properties["subject"], "n/a"); Tuple<EventData, string> qos1Event = Assert.Single(ehMessages.Where(x => TelemetryQoS1Content.Equals(x.Item2, StringComparison.Ordinal))); string qosPropertyName = ConfigurationManager.AppSettings["QoSPropertyName"]; var qos0Notification = new Message(Encoding.UTF8.GetBytes(NotificationQoS0Content)); qos0Notification.Properties[qosPropertyName] = "0"; qos0Notification.Properties["subTopic"] = "tips"; await serviceClient.SendAsync(this.deviceId, qos0Notification); var qos1Notification = new Message(Encoding.UTF8.GetBytes(NotificationQoS1Content)); qos1Notification.Properties["subTopic"] = "firmware-update"; await serviceClient.SendAsync(this.deviceId, qos1Notification); var qos2Notification = new Message(Encoding.UTF8.GetBytes(NotificationQoS2Content)); qos2Notification.Properties[qosPropertyName] = "2"; qos2Notification.Properties["subTopic"] = "critical-alert"; await serviceClient.SendAsync(this.deviceId, qos2Notification); }); Task timeoutTask = Task.Run(async () => { await Task.Delay(TestTimeout); throw new TimeoutException("Test has timed out."); }); await TaskExtensions.WhenSome(new[] { testPromise.Task, testWorkTask, timeoutTask }, 2); this.output.WriteLine(string.Format("Core test completed in {0}", sw.Elapsed)); // making sure that device queue is empty. await Task.Delay(TimeSpan.FromSeconds(3)); DeviceClient deviceClient = DeviceClient.Create( hubConnectionStringBuilder.HostName, new DeviceAuthenticationWithRegistrySymmetricKey(this.deviceId, device.Authentication.SymmetricKey.PrimaryKey)); Client.Message message = await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(1)); Assert.True(message == null, string.Format("Message is not null: {0}", message)); }
public async void MqttServerAndClient() { var testPromise = new TaskCompletionSource(); var tlsCertificate = new X509Certificate2("dotnetty.com.pfx", "password"); Func<Task> closeServerFunc = await this.StartServerAsync(true, ch => { ch.Pipeline.AddLast(TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(true, 256 * 1024), new TestScenarioRunner(this.GetMqttServerScenario, testPromise)); }, testPromise); var group = new MultithreadEventLoopGroup(); Bootstrap b = new Bootstrap() .Group(group) .Channel<TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer<ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); ch.Pipeline.AddLast(TlsHandler.Client(targetHost, null, (sender, certificate, chain, errors) => true)); ch.Pipeline.AddLast( MqttEncoder.Instance, new MqttDecoder(false, 256 * 1024), new TestScenarioRunner(this.GetMqttClientScenario, testPromise)); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); await Task.WhenAny(testPromise.Task, Task.Delay(TimeSpan.FromMinutes(1))); Assert.True(testPromise.Task.IsCompleted); } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }
public async void EchoServerAndClient() { var testPromise = new TaskCompletionSource(); var tlsCertificate = new X509Certificate2("dotnetty.com.pfx", "password"); Func<Task> closeServerFunc = await this.StartServerAsync(true, ch => { ch.Pipeline.AddLast("server logger", new LoggingHandler("SERVER")); ch.Pipeline.AddLast("server tls", TlsHandler.Server(tlsCertificate)); ch.Pipeline.AddLast("server logger2", new LoggingHandler("SER***")); ch.Pipeline.AddLast("server prepender", new LengthFieldPrepender(2)); ch.Pipeline.AddLast("server decoder", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(new EchoChannelHandler()); }, testPromise); var group = new MultithreadEventLoopGroup(); Bootstrap b = new Bootstrap() .Group(group) .Channel<TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Handler(new ActionChannelInitializer<ISocketChannel>(ch => { string targetHost = tlsCertificate.GetNameInfo(X509NameType.DnsName, false); ch.Pipeline.AddLast("client logger", new LoggingHandler("CLIENT")); ch.Pipeline.AddLast("client tls", TlsHandler.Client(targetHost, null, (sender, certificate, chain, errors) => true)); ch.Pipeline.AddLast("client logger2", new LoggingHandler("CLI***")); ch.Pipeline.AddLast("client prepender", new LengthFieldPrepender(2)); ch.Pipeline.AddLast("client decoder", new LengthFieldBasedFrameDecoder(ushort.MaxValue, 0, 2, 0, 2)); ch.Pipeline.AddLast(new TestScenarioRunner(this.GetEchoClientScenario, testPromise)); })); this.Output.WriteLine("Configured Bootstrap: {0}", b); IChannel clientChannel = null; try { clientChannel = await b.ConnectAsync(IPAddress.Loopback, Port); this.Output.WriteLine("Connected channel: {0}", clientChannel); await Task.WhenAny(testPromise.Task, Task.Delay(TimeSpan.FromSeconds(30))); Assert.True(testPromise.Task.IsCompleted, "timed out"); testPromise.Task.Wait(); } finally { Task serverCloseTask = closeServerFunc(); clientChannel?.CloseAsync().Wait(TimeSpan.FromSeconds(5)); group.ShutdownGracefullyAsync(); if (!serverCloseTask.Wait(ShutdownTimeout)) { this.Output.WriteLine("Didn't stop in time."); } } }