private void InitClient(object clientObj)
        {
            // Each one client processing service messages on call GetMessages()
            var client = clientObj as IMyService;

            // 1. Login method call.
            var clientId = client.Login(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());

            try
            {
                do
                {
                    // 2. Infinity GetMessage requests
                    var callbackMessages = client.GetMessages(clientId, TimeSpan.FromSeconds(10));

                    // 3. Processing messages
                    foreach (var callbackMessage in callbackMessages)
                    {
                        var broadcast = callbackMessage as BroadcastMessage;
                        if (broadcast != null)
                        {
                            ProcessBroadcast(clientId, broadcast);
                            continue;
                        }

                        var personal = callbackMessage as PersonalMessage;
                        if (personal != null)
                        {
                            ProcessPersonal(clientId, personal);
                            continue;
                        }

                        SysConsole.WriteQuestionLine($"Unknown message {callbackMessage.GetType()}");
                    }
                } while (true);
            }
            catch (ClientNotFoundedException ex)
            {
                SysConsole.WriteErrorLine($"Client disconnected {ex.ClientId}. Re-login required...");
            }
        }
        public override void Execute(UserSettings settings)
        {
            if (!(settings.Binding is BasicHttpBinding))
            {
                SysConsole.WriteErrorLine($"Supports {nameof(BasicHttpBinding)} only.");
                return;
            }

            switch (settings.AppSide)
            {
            case AppSide.Client:
                var clients = QuestionManager.Choose(
                    new[]
                {
                    1,
                    2,
                    3
                },
                    (o) => o.ToString(),
                    "Choose clients count");

                // Creates callback processors
                for (int i = 0; i < clients; i++)
                {
                    // proxy client
                    var client = CreateClient <IMyService>(settings);

                    // client thread
                    Task.Factory.StartNew(InitClient, client);
                }

                SysConsole.PressAnyKey();
                SysConsole.WriteLine(null, 2);
                break;

            case AppSide.Server:
                CreateServiceHost <IMyService, MyService>(settings).Open();
                QuestionManager.AwaitingClientConnections();
                break;
            }
        }
        /// <inheritdoc/>
        public override void Execute(UserSettings settings)
        {
            var correctBindings = new[]
            {
                typeof(NetTcpBinding),
                typeof(WSHttpBinding),
                typeof(BasicHttpBinding)
            };

            var bindingType = settings.Binding.GetType();

            if (!correctBindings.Contains(bindingType))
            {
                SysConsole.WriteLine($"Binding type should be {string.Join(" or ", correctBindings.Select(binding => binding.Name))}");
                return;
            }

            var reliableSessionFlag = QuestionManager.Choose(
                new[]
            {
                true,
                false
            },
                s => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s.ToString()),
                "Choose reliableSession mode");

            SysConsole.WriteLine();
            SysConsole.WriteQuestionLine($"ReliableSession mode [{reliableSessionFlag.ToString().ToUpper()}] in use now!", 3);

            if (bindingType == typeof(NetTcpBinding))
            {
                var netTcp = ((NetTcpBinding)settings.Binding);
                netTcp.ReliableSession.Enabled = reliableSessionFlag;
                netTcp.Security.Mode           = SecurityMode.None;
            }
            else if (bindingType == typeof(WSHttpBinding))
            {
                var wsDual = ((WSHttpBinding)settings.Binding);
                wsDual.ReliableSession.Enabled = reliableSessionFlag;
                wsDual.Security.Mode           = SecurityMode.None;
            }
            else if (bindingType == typeof(BasicHttpBinding))
            {
                SysConsole.WriteLine($"[{settings.Binding.Name}] [{bindingType.Name}] not supports ReliableSession");
            }
            else
            {
                throw new NotSupportedException(bindingType.FullName);
            }

            switch (settings.AppSide)
            {
            case AppSide.Client:
                var client = CreateClient <IService>(settings);
                SysConsole.WriteQuestion("Single proxy channel client instance!", 1);

                int maxCatchs = 3;
                while (maxCatchs > 0)
                {
                    try
                    {
                        SysConsole.WriteLine($"Call >> {nameof(IService.Method)}");
                        client.Method();
                        Thread.Sleep(2000);
                    }
                    catch (Exception exception)
                    {
                        SysConsole.WriteErrorLine(exception.Message);
                        Thread.Sleep(2000);
                    }

                    try
                    {
                        SysConsole.WriteLine($"Call >> {nameof(IService.OneWayMethodThrowingException)}");
                        client.OneWayMethodThrowingException();
                        Thread.Sleep(2000);
                    }
                    catch (Exception exception)
                    {
                        SysConsole.WriteErrorLine(exception.Message);
                        Thread.Sleep(2000);
                    }

                    try
                    {
                        SysConsole.WriteLine($"Call >> {nameof(IService.MethodThrowingException)}");
                        client.MethodThrowingException();
                        Thread.Sleep(2000);
                    }
                    catch (Exception exception)
                    {
                        SysConsole.WriteErrorLine(exception.Message);
                        Thread.Sleep(2000);
                    }
                    maxCatchs--;
                }

                Console.ReadKey();
                break;

            case AppSide.Server:
                CreateServiceHost <IService, Service>(settings).Open();
                QuestionManager.AwaitingClientConnections();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        /// <inheritdoc/>
        public override void Execute(UserSettings settings)
        {
            switch (settings.AppSide)
            {
            case AppSide.Client:
                SysConsole.WriteLine();
                SysConsole.WriteQuestionLine("A correct flow when we logged in -> said hello world -> logged out.", 2);

                while (true)
                {
                    var client = CreateClient <IMyService>(settings);
                    try
                    {
                        while (true)
                        {
                            var methodName = QuestionManager.Choose(
                                new[]
                            {
                                nameof(IMyService.Login),
                                nameof(IMyService.SayHello),
                                nameof(IMyService.Logout),
                            },
                                s => s.ToString(),
                                "Choose contract action call");
                            switch (methodName)
                            {
                            case nameof(IMyService.Login):
                                client.Login();
                                break;

                            case nameof(IMyService.Logout):
                                client.Logout();
                                break;

                            case nameof(IMyService.SayHello):
                                client.SayHello();
                                break;
                            }
                        }
                    }
                    catch (Exception exception)
                    {
                        SysConsole.WriteErrorLine(exception.Message);
                        var answer = QuestionManager.Choose(
                            new[]
                        {
                            "Yes",
                            "No"
                        },
                            s => s.ToString(),
                            "Create new connection?");

                        if (answer == "No")
                        {
                            break;
                        }
                    }
                }
                break;

            case AppSide.Server:
                var service = CreateServiceHost <IMyService, MyService>(settings);
                service.Open();
                SysConsole.WriteQuestion("Service is working.");
                QuestionManager.AwaitingClientConnections();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }