public G9SuperNetCoreSocketClient(G9ClientConfig clientConfig, IG9Logging customLogging = null,
                                   string privateKeyForSslConnection = null, string clientUniqueIdentity = null,
                                   Assembly[] commandAssemblies      = null,
                                   TAccount customAccount            = null, TSession customSession = null) : base(clientConfig, customLogging,
                                                                                                                   privateKeyForSslConnection, clientUniqueIdentity, commandAssemblies, customAccount, customSession)
 {
 }
        /// <summary>
        ///     <para>Constructor</para>
        ///     <para>Initialize requirement for packet management</para>
        ///     <para>The package is made of the following items:</para>
        ///     <para>
        ///         PacketTypeSize(Const 1 byte) + (CommandSize * 16) + PacketSpecifyBodySize((BodySize * 16).ToString().Length) +
        ///         (BodySize * 16) + PacketRequestIdSize(Const 16 byte => Guid.NewGuid().ToByteArray().Length)
        ///     </para>
        /// </summary>
        /// <param name="oPacketCommandSize">Specify packet command size</param>
        /// <param name="oPacketBodySize">Specify packet body size</param>
        /// <param name="oEncoding">Specify encoding and decoding type</param>
        /// <param name="logging">Specified custom logging system</param>

        #region G9PacketManagement

        public G9PacketManagement(byte oPacketCommandSize, byte oPacketBodySize, G9Encoding oEncoding,
                                  IG9Logging logging)
        {
            _logging    = logging;
            CommandSize = oPacketCommandSize;
            BodySize    = oPacketBodySize;

            CalculateBodySize    = (ushort)(BodySize * 16);
            CalculateCommandSize = CommandSize * 16;
            EncodingHandler      = oEncoding;
        }
        /// <summary>
        ///     Constructor
        ///     Initialize requirement
        /// </summary>
        /// <param name="commandAssemblies">Specified command assemblies (find command in specified assembly)</param>
        /// <param name="logging">Specified custom logging system</param>
        /// <param name="oCommandSize">
        ///     Specify max command size
        ///     Example: if set "n" length is "n*16" => if set 1 length is 16 then maximum command name length is 16 byte or
        ///     character
        /// </param>
        /// <param name="onUnhandledCommand">Specified event on unhandled command</param>

        #region G9CommandHandler

        public G9CommandHandler(Assembly[] commandAssemblies, IG9Logging logging, int oCommandSize,
                                Action <G9SendAndReceivePacket, TAccount> onUnhandledCommand)
        {
            // Set assembly of commands
            _commandAssembly = commandAssemblies ?? throw new ArgumentNullException(nameof(commandAssemblies));

            // Set command size
            CommandSize = oCommandSize * 16;

            // Set logging
            _logging = logging;

            // Set on unhandled command
            _onUnhandledCommand = onUnhandledCommand;

            // Initialize collection
            _accessToCommandDataTypeCollection = new SortedDictionary <string, CommandDataType <TAccount> >();
            _instanceCommandCollection         = new SortedDictionary <string, object>();

            // Initialize all command
            InitializeAllCommand();
        }
        /// <summary>
        ///     <para>Constructor</para>
        ///     <para>Initialize requirement And Set config</para>
        /// </summary>
        /// <param name="clientConfig">Specify client configuration</param>
        /// <param name="customLogging">Specified custom logging system</param>
        /// <param name="privateKeyForSslConnection">
        ///     <para>
        ///         Notice: This is not a certificate password, it is a private, shared key between the client and the server for
        ///         secure connection (SSL)
        ///     </para>
        ///     <para>Specified custom private key</para>
        /// </param>
        /// <param name="clientUniqueIdentity">
        ///     <para>Specify a unique identity string from client</para>
        ///     <para>Used for ssl connection</para>
        /// </param>
        /// <param name="commandAssemblies">
        ///     <para>Specified command assemblies (find command in specified assembly)</para>
        ///     <para>If set null, mean all assembly access</para>
        /// </param>
        /// <param name="customAccount">If need set account with custom initialized account, Set it.</param>
        /// <param name="customSession">If need set session with custom initialized session, Set it.</param>

        #region G9SuperNetCoreClientBase

        protected AG9SuperNetCoreClientBase(G9ClientConfig clientConfig, IG9Logging customLogging = null,
                                            string privateKeyForSslConnection = null, string clientUniqueIdentity = null, Assembly[] commandAssemblies = null,
                                            TAccount customAccount            = null, TSession customSession = null)
        {
            // Set command assemblies
            // ReSharper disable once ConvertToNullCoalescingCompoundAssignment
            commandAssemblies = commandAssemblies ?? AppDomain.CurrentDomain.GetAssemblies();

            // Set logging system
            _logging = customLogging ?? new G9LoggingClient();

            // Set configuration
            Configuration = clientConfig;

            // Initialize main account utilities
            _mainAccountUtilities =
                new G9AccountUtilities <TAccount, G9ClientAccountHandler, G9ClientSessionHandler>
            {
                Account = customAccount ?? new TAccount()
            };

            // Initialize account and session
            var session = customSession ?? new TSession();

            session.InitializeAndHandlerAccountAndSessionAutomaticFirstTime(_mainAccountUtilities.SessionHandler =
                                                                                new G9ClientSessionHandler
            {
                // Set send command sync
                Session_SendCommandByName = SendCommandByName,
                // Set send command async
                Session_SendCommandByNameAsync = SendCommandByNameAsync,
                // Set session encoding
                Session_GetSessionEncoding = () => Configuration.EncodingAndDecoding,
                // Set account
                Core_SetAccount = () => _mainAccountUtilities.Account
            }, 0, IPAddress.Any);
            _mainAccountUtilities.Account.InitializeAndHandlerAccountAndSessionAutomaticFirstTime(
                _mainAccountUtilities.AccountHandler = new G9ClientAccountHandler(), session);

            // Initialize packet management
            _packetManagement = new G9PacketManagement(Configuration.CommandSize, Configuration.BodySize,
                                                       Configuration.EncodingAndDecoding, _logging);

            // Set packet size
            _packetSize = _packetManagement.MaximumPacketSize;

            // Initialize state object
            _stateObject =
                new G9SuperNetCoreStateObjectClient(_packetSize, _mainAccountUtilities.Account.Session.SessionId);

            // Set log
            if (_logging.CheckLoggingIsActive(LogsType.EVENT))
            {
                _logging.LogEvent(LogMessage.CreateAndInitializeClient, G9LogIdentity.CREATE_CLIENT,
                                  LogMessage.SuccessfulOperation);
            }

            // Initialize command handler
            _commandHandler = new G9CommandHandler <TAccount>(commandAssemblies, _logging, Configuration.CommandSize,
                                                              OnUnhandledCommandHandler);

            // Set command call back
            CommandHandlerCallback = _commandHandler;

            // ######################## Add default command ########################
            // G9 Echo Command
            _commandHandler.AddCustomCommand <string>(nameof(G9ReservedCommandName.G9EchoCommand),
                                                      G9EchoCommandReceiveHandler, null);
            // G9 Test Send Receive
            _commandHandler.AddCustomCommand <string>(nameof(G9ReservedCommandName.G9TestSendReceive),
                                                      G9TestSendReceiveCommandReceiveHandler, null);
            // G9 Ping Command
            _commandHandler.AddCustomCommand <string>(nameof(G9ReservedCommandName.G9PingCommand),
                                                      G9PingCommandReceiveHandler, null);
            // G9 Authorization Command
            _commandHandler.AddCustomCommand <byte[]>(nameof(G9ReservedCommandName.G9Authorization),
                                                      AuthorizationReceiveHandler, null);

            // Set reconnect try count - use when client disconnected
            _reconnectTryCount = Configuration.ReconnectTryCount;

            // Set private key
            if (string.IsNullOrEmpty(privateKeyForSslConnection))
            {
                return;
            }
            // Set private key
            _privateKey = privateKeyForSslConnection;
            // Set client unique identity
            _clientIdentity       = string.IsNullOrEmpty(clientUniqueIdentity)
                ? _clientIdentity = Guid.NewGuid().ToString("N")
                : _clientIdentity = clientUniqueIdentity.Length < 16
                    ? clientUniqueIdentity + Guid.NewGuid().ToString("N")
                    : clientUniqueIdentity;
        }