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;
}
我希望服务器检测到客户端断开连接。
解决方案
推荐阅读
- python - 在两个客户端之间共享类实例(python)
- webpack - 带有 Cookie 的 Webpack devServer 转发
- javascript - Discord API:缺少权限
- python - 比较 QLineEdit() 和 csv 文件值
- php - 使用 Neo4J PHP Client 时如何显示和执行 PHP 语句?
- php - 如何使用 PHP 使用 MySQL COUNT() 函数
- javascript - 使返回的 JSON 可以被 Flask 中的 javascript 读取
- javascript - 为什么 react-native 似乎无法识别我目录中的 png?
- google-apps-script - 从谷歌表中获取单元格值作为自定义日期格式
- intellij-idea - 尝试通过 IntelliJ 连接 Bigquery