public ZMsg recv() {
    ZMsg reply = null;
    Poller items = new Poller(1);
    items.register(client, Poller.POLLIN);
    if (items.poll(timeout * 1000) == -1) {
      return null;
    }

    if (items.pollin(0)) {
      ZMsg msg = ZMsg.recvMsg(client, 0); // 非阻塞
      if (verbose) {
        log.format("I:receive reply");
        msg.dump(log.out());
      }
      assert (msg.size() >= 4);
      ZFrame empty = msg.pop();
      assert (empty.getData().length == 0);
      empty.destroy();
      ZFrame header = msg.pop();
      assert (MDP.C_CLIENT.equals(header.toString()));
      header.destroy();

      ZFrame replyService = msg.pop();
      replyService.destroy();

      reply = msg;
    }
    return reply;
  }
 /**
  * 发送的消息格式: [000] [006] MDPC01 [004] echo [011] Hello world
  *
  * @param service
  * @param request
  */
 public void send(String service, ZMsg request) {
   assert (request == null);
   request.addFirst(service); // 在reqeust前面添加帧
   request.addFirst(MDP.C_CLIENT.newFrame());
   request.addFirst("");
   if (verbose) {
     log.format("I:send request to '%s' service.\n", service);
     request.dump(log.out());
   }
   request.send(client);
 }
Example #3
0
  //  The main task is an LRU queue with heartbeating on workers so we can
  //  detect crashed or blocked worker tasks:
  public static void main(final String[] args) {
    final ZContext ctx = new ZContext();
    final Socket frontend = ctx.createSocket(ZMQ.ROUTER);
    final Socket backend = ctx.createSocket(ZMQ.ROUTER);
    frontend.bind("tcp://*:5555"); //  For clients
    backend.bind("tcp://*:5556"); //  For workers

    //  List of available workers
    final ArrayList<Worker> workers = new ArrayList<Worker>();

    //  Send out heartbeats at regular intervals
    long heartbeat_at = System.currentTimeMillis() + HEARTBEAT_INTERVAL;

    while (true) {
      final PollItem items[] = {
        new PollItem(backend, ZMQ.Poller.POLLIN), new PollItem(frontend, ZMQ.Poller.POLLIN)
      };
      //  Poll frontend only if we have available workers
      final int rc = ZMQ.poll(items, workers.size() > 0 ? 2 : 1, HEARTBEAT_INTERVAL);
      if (rc == -1) {
        break; //  Interrupted
      }

      //  Handle worker activity on backend
      if (items[0].isReadable()) {
        //  Use worker address for LRU routing
        final ZMsg msg = ZMsg.recvMsg(backend);
        if (msg == null) {
          break; //  Interrupted
        }

        //  Any sign of life from worker means it's ready
        final ZFrame address = msg.unwrap();
        final Worker worker = new Worker(address);
        worker.ready(workers);

        //  Validate control message, or return reply to client
        if (msg.size() == 1) {
          final ZFrame frame = msg.getFirst();
          final String data = new String(frame.getData());
          if (!data.equals(PPP_READY) && !data.equals(PPP_HEARTBEAT)) {
            System.out.println("E: invalid message from worker");
            msg.dump(System.out);
          }
          msg.destroy();
        } else {
          msg.send(frontend);
        }
      }
      if (items[1].isReadable()) {
        //  Now get next client request, route to next worker
        final ZMsg msg = ZMsg.recvMsg(frontend);
        if (msg == null) {
          break; //  Interrupted
        }
        msg.push(Worker.next(workers));
        msg.send(backend);
      }

      //  We handle heartbeating after any socket activity. First we send
      //  heartbeats to any idle workers if it's time. Then we purge any
      //  dead workers:

      if (System.currentTimeMillis() >= heartbeat_at) {
        for (final Worker worker : workers) {

          worker.address.send(backend, ZFrame.REUSE + ZFrame.MORE);
          final ZFrame frame = new ZFrame(PPP_HEARTBEAT);
          frame.send(backend, 0);
        }
        heartbeat_at = System.currentTimeMillis() + HEARTBEAT_INTERVAL;
      }
      Worker.purge(workers);
    }

    //  When we're done, clean up properly
    while (workers.size() > 0) {
      final Worker worker = workers.remove(0);
    }
    workers.clear();
    ctx.destroy();
  }