在同一个套接字上使用zmq_poll和zmq_send()

时间:2013-08-14 13:15:35

标签: zeromq

我对api of zmq_poll中的警告感到困惑:“zmq_send()函数将清除套接字上的所有挂起事件。因此,如果使用zmq_poll()监视套接字上的输入,请使用它在输出之前,并在每次zmq_poll()调用之后处理所有事件。“

我不明白这意味着什么。由于事件是级别触发的。如果我调用zmq_send()然后调用zmq_poll(),套接字缓冲区中的任何待处理消息都应立即再次触发zmq_poll。为什么需要在输出之前“使用它(zmq_poll)”或“在每次zmq_poll()调用之后处理所有事件”?

1 个答案:

答案 0 :(得分:1)

我明白你的意思,文档令人困惑。这是一个简单的Java测试,使用带有轮询器的客户端DEALER套接字(来自asyncsrv)。服务器向客户端发送3条消息。客户端轮询并输出它收到的每条消息。我在客户端添加了send()来测试你的理论。假设send()清除了轮询器,我们希望客户端只输出一条消息:

服务器

public static void main(String[] args) {
    Context context = ZMQ.context(1);
    ZMQ.Socket server = context.socket(ZMQ.ROUTER);
    server.bind("tcp://*:5555");

    server.sendMore("clientId");
    server.send("msg1");

    server.sendMore("clientId");
    server.send("msg2");

    server.sendMore("clientId");
    server.send("msg3");
}


<强>客户端

public void run() {
    socket = context.socket(ZMQ.DEALER);
    socket.setIdentity("clientId".getBytes());
    socket.connect("tcp://localhost:5555");

    ZMQ.Poller poller = new ZMQ.Poller(1);
    poller.register(socket, ZMQ.Poller.POLLIN);

    while (true) {
        poller.poll();
        if (poller.pollin(0)) {
            String msg = socket.recvStr(0);
            System.out.println("Client got msg: " + msg);
            socket.send("whatever", 0);
        }
    }
}

...输出

Client got msg: msg1
Client got msg: msg2
Client got msg: msg3

根据结果,执行send()并不会清除socket的轮询器,这应该是显而易见的原因。我们使用POLLIN配置了轮询器,这意味着轮询器会将入站消息侦听到socket。在执行socket.send()时,它会创建出站消息,轮询器不会在其上侦听。

希望它有所帮助...