ZMQ套接字 - 在提供所有请求时断开连接

时间:2017-10-30 07:49:45

标签: sockets zeromq jzmq

我正在尝试在Java中实现ZMQ REQ/REP 模型

我有一个服务器 -role,在帖子5564上运行,作为Replier

ZMQ.Socket repSock = context.socket(ZMQ.REP);

我有一个客户端 -role,在帖子5563上运行

ZMQ.Socket syncclient = context.socket(ZMQ.REQ);

我在中间有一个代理 - 服务器,它传递请求和响应

ZMQ.proxy(reqSocket, repSocket, null);

拥有代理的好处是我可以添加多个服务器

repSocket.connect("tcp://" + addr.getHostAddress() + ":" + port);

哪种方法正常。

现在,当我从代理

中删除服务器节点时
repSocket.disconnect("tcp://" + addr.getHostAddress() + ":" + port);

客户端被卡住了,因为已经发出请求并且 REQ -socket等待响应。

因此,流程停留在 syncclient.recvStr()

for (int request_nbr = 0; request_nbr < (request_nbr + 1); request_nbr++) {          

    syncclient.send(str.getBytes(),0);
    System.out.println("Send Dataaaa....... " );
    String data = syncclient.recvStr(Charset.defaultCharset());
    System.out.println(" here.. " +data);

    request_nbr++;
}  

我搜索过,无法找到跟踪REQ - 套接字

的方法

我需要两件事中的任何一件:

  1. 跟踪我即将断开连接的Socket - 实例的方法,等待所有邮件都被处理,以便syncclient.recvStr()不会被阻止

  2. 重置syncclient - 套接字的方法,以便我可以不间断地响应REQ/REP

1 个答案:

答案 0 :(得分:1)

在实际场景中,请避免使用ZeroMQ .send() / .recv()方法的阻止模式,并更好地使用.poll()

虽然这可能需要更多SLOC代码,但结果会让您处于控制之中,而阻塞SLOC会从您的代码中获取所有控制权,并且在(如果有的话)下一条消息之前您无法做很多事情交付。这是一个非常错误的设计实践,除了最简单的教科书例子,它实际上是对现实世界的反模式。

所以,不要指望问题2 以某种方式神奇地解决,这不是ZeroMQ API的一部分(对于许多相当大声传播的原因)。如果API版本和使用环境允许,或者根本不使用简单的 .setsockopt( ZMQ.REQ_RELAXED, 1 ) 模式,则可以更好地在 REQ/REP 之间做出决定(因为它已知)陷入无法挽回的共同死锁的风险(参考我关于这个问题的其他帖子,这种现象既有说明也有无数次解释)。)

以类似的方式,在您从未阅读过ZeroMQ规范和/或文档以及ZeroMQ“最佳实践”的情况下,询问问题1 似乎是合理的。花了一些时间在这里,你的选择将是清晰的。没有这样的工具可以用来做这个内置的。如果需要为她/他自己的需要添加任何类似的非核心逻辑,可以添加一些附加组件。唯一可以间接影响aSocket.close()行为的设置可在 .setsockopt( ZMQ.LINGER, 0 ) 中找到,这有助于防止系统过渡到有效的挂断状态,一次{{ 1}}无限期地等待一个在情况下永远不会发生的状态,当消息队列仍然是非空的时候(消息仍在等待传递)。

进入分布式系统设计就像进入一个新世界。没有保证序列(非串行代码执行路径发生)。没有任何本地控制远程实体,它们的状态,它们的失败,它们的存在,它们的实际ZeroMQ API版本。

确实是一个充满挑战的世界。

<强> N.b:
您可能已经知道,在不使用代理的情况下,可以aSocket .connect() - 实例(更好的aSocket - 实例的访问点)到多个远程端。通过一些额外的aSocket调整 .setsockopt() 到值1,将有助于更好地管理循环分配策略,而不管用于实际消息传递的传输类(ZMQ.IMMEDIATE)。一切都在你的指尖。