public Task StartAsync(HostingApplication hostingApplication, CancellationToken cancellationToken)
        {
            _routerSocket = new RouterSocket();
            _routerSocket.Bind($"tcp://{_hostingOptions.Host}");
            _routerSocket.ReceiveReady += RouterSocket_ReceiveReady;
            _dealerSocket = new DealerSocket();
            _dealerSocket.Bind(INPROC_SERVER_URL);
            _dealerSocket.ReceiveReady += DealerSocket_ReceiveReady;

            _poller = new NetMQPoller {
                _routerSocket, _dealerSocket
            };
            _poller.RunAsync();
            _workerPoller = new NetMQPoller();
            async void OnReceiveReady(object sender, NetMQSocketEventArgs args)
            {
                NetMQMessage receiveMessage = args.Socket.ReceiveMultipartMessage();
                string       address        = receiveMessage.Pop().ConvertToString();
                string       content        = receiveMessage.Last().ConvertToString(Encoding.UTF8);
                OwinContext  owinContext    = null;
                long         startTimestamp = Stopwatch.GetTimestamp();

                _logger.LogInformation($"Request starting tcp://{_hostingOptions.Host} {content}");
                owinContext = hostingApplication.CreateContext(content);
                try
                {
                    await hostingApplication.ProcessRequestAsync(owinContext);
                }
                catch (Exception ex)
                {
                    owinContext.Response.Error(ex.Message);
                    throw;
                }
                finally
                {
                    string sendContent = _serializer.Serialize(owinContext.Response);
                    _logger.LogInformation($"Request finished in {new TimeSpan((long)(TimestampToTicks * (Stopwatch.GetTimestamp() - startTimestamp))).TotalMilliseconds}ms {sendContent}");
                    NetMQMessage sendMessage = new NetMQMessage();
                    sendMessage.Append(address);
                    sendMessage.AppendEmptyFrame();
                    sendMessage.Append(sendContent, Encoding.UTF8);
                    args.Socket.SendMultipartMessage(sendMessage);
                    hostingApplication.DisponseContext(owinContext);
                }
            }

            foreach (var item in Enumerable.Range(0, _hostingOptions.ProcessCount))
            {
                NetMQSocket process = new DealerSocket();
                process.Connect(INPROC_SERVER_URL);
                process.ReceiveReady += OnReceiveReady;
                _workerPoller.Add(process);
            }

            _workerPoller.RunAsync();
            return(Task.CompletedTask);
        }