试图测试pub / sub的简单实现。我发现,如果我将订阅者留下并发送消息,则订阅者不会全部收到订阅者。有时候所有人都收到了,有时候是部分的,有时甚至不会收到整套。
运行订阅服务器(保持运行状态),然后多次运行发布服务器。
import org.zeromq.ZMQ;
import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Socket;
public static void main (String[] args) {
// Prepare our context and subscriber
Context context = ZMQ.context(1);
Socket subscriber = context.socket(ZMQ.SUB);
subscriber.connect("tcp://localhost:5563");
subscriber.subscribe("B".getBytes());
System.out.println("Starting Subscriber..");
int i = 0;
while (true) {
String address = subscriber.recvStr();
String contents = subscriber.recvStr();
System.out.println(address+":"+new String(contents) + ": "+(i));
i++;
}
}
}
出版商:
import org.zeromq.ZMQ;
import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Socket;
public class TestPublisher {
public static void main (String[] args) throws Exception {
Context context = ZMQ.context(1);
Socket publisher = context.socket(ZMQ.PUB);
publisher.bind("tcp://*:5563");
System.out.println("Starting Publisher..");
publisher.setIdentity("B".getBytes());
publisher.setHWM(1000);
for (int i = 0; i < 10; i++) {
Thread.sleep(10l);
publisher.sendMore("B");
boolean isSent = publisher.send("We would like to see this:"+i);
System.out.println("Message was sent "+i+" , "+isSent);
}
Thread.sleep(1000);
publisher.close ();
context.term ();
}
}
答案 0 :(得分:2)
经过一些调试后发现问题是,在发布套接字绑定时花了一点时间并试图发布刚丢弃的消息。在初始绑定上添加100ms的简单睡眠修复此问题。在prod环境中,发布者已经在启动时受到约束。
猜猜这是一个单线解决方案。现在,具有平均数据量的pub / sub的所有消息都可以正常工作而不会丢失任何数据。请参阅下面的发布商的代码段更新。
import org.zeromq.ZMQ;
import org.zeromq.ZMQ.Context;
import org.zeromq.ZMQ.Socket;
public class TestPublisher {
public static void main (String[] args) throws Exception {
Context context = ZMQ.context(1);
Socket publisher = context.socket(ZMQ.PUB);
publisher.bind("tcp://*:5563");
System.out.println("Starting Publisher..");
publisher.setIdentity("B".getBytes());
// for testing setting sleep at 100ms to ensure started.
Thread.sleep(100l);
for (int i = 1; i <= 10; i++) {
publisher.sendMore("B");
boolean isSent = publisher.send("X("+System.currentTimeMillis()+"):"+i);
System.out.println("Message was sent "+i+" , "+isSent);
}
publisher.close ();
context.term ();
}
}
答案 1 :(得分:0)
zmq guide的第5章“高级发布 - 子模式”涵盖了可靠的发布/订阅。但是,如果您的服务器始终在生产中运行,那么除了您已经投入的睡眠以使测试正常工作之外,您不需要做任何其他事情。
如果您真的想解决订阅者消息的问题,第5章中的“获取带外快照”示例将涵盖它。