NetMQ路由器套接字(服务器)能否检测到请求套接字(客户端)是否已超时?

时间:2019-07-17 15:23:48

标签: c# netmq

我正在使用NetMQ v3.3.3.4开发一个简单的服务器(RouterSocket)-客户端(RequestSocket)方案。除了一件事,它按预期工作。

有时服务器花费的时间太长,无法返回响应,并且客户端达到超时。此行为是所需的。这里的问题是服务器没有检测到客户端已经消失,而是继续处理请求。在某个时候,处理完成,服务器尝试返回响应。服务器再也没有意识到客户端不再在听,并且认为响应已成功传递。这会导致误导用户反馈和错误的日志文件条目。

服务器是否可以检测客户端是否仍在等待响应?

服务器

        private void Listen()
        {
            using (var poller = new NetMQPoller())
            using (var responseSocket = new RouterSocket())
            using (var poisonedSocket = new ResponseSocket())
            {
                responseSocket.Bind(_bindServerString);
                poisonedSocket.Bind(_bindTerminationString);

                var keepAliveTimer = new NetMQTimer(KeepAliveInterval);
                keepAliveTimer.Elapsed += (s, a) =>
                {
                    _monitorPublisher.Status["KeepAlive"] = Application.LocalDateTime.Now.ToString();
                    _monitorPublisher.SendStatus();
                };

                poisonedSocket.ReceiveReady += (s, a) =>
                {
                    a.Socket.ReceiveFrameBytes();
                    poller.Stop();
                };

                responseSocket.ReceiveReady += (s, a) =>
                {
                    try
                    {
                        bool header = true;
                        byte[] response = null;
                        while (a.Socket.TryReceiveFrameBytes(out byte[] message))
                        {
                            // Using a ROUTER socket...
                            if (header)
                            {
                                // We have to first, wait for the first frame,
                                // which is the address (header) of the REQ socket.
                                // Afterwards, we have to wait for the second frame,
                                // which is 0 and act as a delimiter between the REQ address
                                // and the actual body of the request.
                                a.Socket.SendFrame(message, true);

                                // Once we have the header delimiter, we can be sure that
                                // the next frame is the actual request.
                                header = !(message.Length == 0);
                            }
                            else
                            {
                                // Parse the request and return a response
                                BridgeRequestReceived?.Invoke(message, out response);
                                a.Socket.SendFrame(response);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Instance.Log(e);
                    }
                };

                poller.Add(keepAliveTimer);
                poller.Add(responseSocket);
                poller.Add(poisonedSocket);

                Logger.Instance.Log($"Receiving requests on: {_bindServerString}", Application.LogCategory.Info);
                poller.Run();

                responseSocket.Close();
                poisonedSocket.Close();
            }
        }

客户

        private string SendRequest(IBridgeMessage request, out Exception e)
        {
            e = null;
            string response = null;
            using (var socket = new RequestSocket())
            {
                try
                {
                    socket.Connect(_endpoint);
                    byte[] encryptedRequest = CryptoAES.StandardCrypto.Encrypt(Encoding.UTF8.GetBytes(NMTBridgeMessageFactory.Serialize(request)));

                    socket.SendFrame(encryptedRequest);
                    if (socket.TryReceiveFrameBytes(_timeout, out byte[] reply))
                    {
                        response = Encoding.UTF8.GetString(CryptoAES.StandardCrypto.Decrypt(reply));
                    }
                    else
                    {
                        e = new TimeoutException("Timeout occured!");
                        response = null;
                    }
                }
                catch (Exception ex)
                {
                    e = ex;
                    response = null;
                }
            }

            return response;
        }

我希望服务器检测到客户端断开连接。

0 个答案:

没有答案