我需要使用 0MQ 为回复/请求事务添加超时。这通常是如何实现的?我尝试使用以下方法:
socket.setReceiveTimeOut();
和
socket.setSendTimeout();
但它们似乎会导致空指针异常。
本质上,如果接收请求的应用程序不可用,我希望应用程序在 10 秒后超时。
任何帮助表示赞赏。
谢谢!
我认为 jzmq 应该ZMQException在 recv 超时时抛出一个,但是没有ZMQException, when err = EAGAIN。
https://github.com/zeromq/jzmq/blob/master/jzmq-jni/src/main/c%2B%2B/Socket.cpp
static
zmq_msg_t *do_read(JNIEnv *env, jobject obj, zmq_msg_t *message, int flags)
{
void *socket = get_socket (env, obj);
int rc = zmq_msg_init (message);
if (rc != 0) {
raise_exception (env, zmq_errno());
return NULL;
}
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
rc = zmq_recvmsg (socket, message, flags);
#else
rc = zmq_recv (socket, message, flags);
#endif
int err = zmq_errno();
if (rc < 0 && err == EAGAIN) {
rc = zmq_msg_close (message);
err = zmq_errno();
if (rc != 0) {
raise_exception (env, err);
return NULL;
}
return NULL;
}
if (rc < 0) {
raise_exception (env, err);
rc = zmq_msg_close (message);
err = zmq_errno();
if (rc != 0) {
raise_exception (env, err);
return NULL;
}
return NULL;
}
return message;
}
我想知道您的空指针是否与您的套接字的创建方式有关。我过去成功设置了套接字超时。
当我使用 JeroMQ 库(ZMQ 的本机 Java 实现)时,以下内容对我有用。我用它来帮助通过 ZMQ 执行 REQ-REP 命令。
ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket sock = context.socket(ZMQ.REQ);
sock.setSendTimeOut(10000); // 10 second send timeout
sock.setReceiveTimeOut(10000); // 10 second receive timeout
if (sock.connect("tcp://127.0.0.1:1234")) {
if (sock.send(/* insert data here */)) {
/* Send was successful and did not time out. */
byte[] replyBytes = null;
replyBytes = sock.recv();
if (null == replyBytes) {
/* Receive timed out. */
} else {
/* Receive was successful. Do something with replyBytes. */
}
}
}
这[回复/请求事务的超时]通常是如何完成的?
我很遗憾地确认,ZeroMQ 原生 API 中没有这样的东西。进行异步交付的原则意味着,交付的发生没有限制(在尽力而为的调度模型中,或者根本没有)。
如果您是 ZeroMQ 新手,您可能会喜欢快速阅读这 5 秒的阅读内容,了解 [ ZeroMQ 层次结构在不到 5 秒的时间内] 部分中的主要概念元素。
我想......如果......接收请求不是......在10 秒后超时......
可以将您的.recv()-method 调用用法设计为在 -method 筛选器之后进行预测试/受保护.poll( 10000 ),以在发出(或不发出)调用之前首先明确检测是否存在确实传递到您的应用程序代码的任何消息实际的.recv()- 方法仅在先前 POSACK ed 消息准备好在本地读取时,或者可以使用更“原始”的方法,使用具有方法的非阻塞形式的处理程序,通过调用.recv( ZMQ_NOBLOCK )-标记不要在“那里”花费一毫秒,以防“那里”现在没有要从本地端Context()引擎实例读取的消息,并在您的代码中相应地处理每种情况。
还要注意,使用REQ/REP-Scalable Formal Communication Archetype 模式不会更容易,因为有一个强制性的双向步舞(当然,如果不是故意人为ZMQ_RELAXED),所以 FSA 背靠背-connected-FSA-s 仍然需要等待下一个“预期的”远程事件,然后才能有机会处理下一个本地事件。如果对细节感兴趣,会发现很多关于不可避免的、无法挽救的相互死锁的帖子,这种情况肯定会发生REQ/REP,我们只是不知道它什么时候发生,但肯定会发生。