Exemple #1
0
  @Override
  public void activate_out() {
    io_object.set_pollout(handle);

    //  Speculative write: The assumption is that at the moment new message
    //  was sent by the user the socket is probably available for writing.
    //  Thus we try to write the data to socket avoiding polling for POLLOUT.
    //  Consequently, the latency should be better in request/reply scenarios.
    out_event();
  }
Exemple #2
0
  public void plug(IOThread io_thread_, SessionBase session_) {
    assert (!plugged);
    plugged = true;

    //  Connect to session object.
    assert (session == null);
    assert (session_ != null);
    session = session_;
    socket = session.get_soket();

    io_object = new IOObject(null);
    io_object.set_handler(this);
    //  Connect to I/O threads poller object.
    io_object.plug(io_thread_);
    io_object.add_fd(handle);
    io_enabled = true;

    //  Send the 'length' and 'flags' fields of the identity message.
    //  The 'length' field is encoded in the long format.
    greeting_output_buffer.put((byte) 0xff);
    greeting_output_buffer.putLong(options.identity_size + 1);
    greeting_output_buffer.put((byte) 0x7f);

    io_object.set_pollin(handle);
    //  When there's a raw custom encoder, we don't send 10 bytes frame
    boolean custom = false;
    try {
      custom = options.encoder != null && options.encoder.getDeclaredField("RAW_ENCODER") != null;
    } catch (SecurityException e) {
    } catch (NoSuchFieldException e) {
    }

    if (!custom) {
      outsize = greeting_output_buffer.position();
      outbuf = new Transfer.ByteBufferTransfer((ByteBuffer) greeting_output_buffer.flip());
      io_object.set_pollout(handle);
    }

    //  Flush all the data that may have been already received downstream.
    in_event();
  }
Exemple #3
0
  private boolean handshake() {
    assert (handshaking);

    //  Receive the greeting.
    while (greeting.position() < GREETING_SIZE) {
      final int n = read(greeting);
      if (n == -1) {
        error();
        return false;
      }

      if (n == 0) return false;

      //  We have received at least one byte from the peer.
      //  If the first byte is not 0xff, we know that the
      //  peer is using unversioned protocol.
      if (greeting.array()[0] != -1) break;

      if (greeting.position() < 10) continue;
      //  Inspect the right-most bit of the 10th byte (which coincides
      //  with the 'flags' field if a regular message was sent).
      //  Zero indicates this is a header of identity message
      //  (i.e. the peer is using the unversioned protocol).
      if ((greeting.array()[9] & 0x01) == 0) break;

      //  The peer is using versioned protocol.
      //  Send the rest of the greeting, if necessary.
      if (greeting_output_buffer.limit() < GREETING_SIZE) {
        if (outsize == 0) io_object.set_pollout(handle);
        int pos = greeting_output_buffer.position();
        greeting_output_buffer.position(10).limit(GREETING_SIZE);
        greeting_output_buffer.put((byte) 1); // Protocol version
        greeting_output_buffer.put((byte) options.type); // Socket type
        greeting_output_buffer.position(pos);
        outsize += 2;
      }
    }

    //  Position of the version field in the greeting.
    final int version_pos = 10;

    //  Is the peer using the unversioned protocol?
    //  If so, we send and receive rests of identity
    //  messages.
    if (greeting.array()[0] != -1 || (greeting.array()[9] & 0x01) == 0) {
      encoder = new_encoder(Config.out_batch_size.getValue(), null, 0);
      encoder.set_msg_source(session);

      decoder = new_decoder(Config.in_batch_size.getValue(), options.maxmsgsize, null, 0);
      decoder.set_msg_sink(session);

      //  We have already sent the message header.
      //  Since there is no way to tell the encoder to
      //  skip the message header, we simply throw that
      //  header data away.
      final int header_size = options.identity_size + 1 >= 255 ? 10 : 2;
      ByteBuffer tmp = ByteBuffer.allocate(header_size);
      encoder.get_data(tmp);
      assert (tmp.remaining() == header_size);

      //  Make sure the decoder sees the data we have already received.
      inbuf = greeting;
      greeting.flip();
      insize = greeting.remaining();

      //  To allow for interoperability with peers that do not forward
      //  their subscriptions, we inject a phony subsription
      //  message into the incomming message stream. To put this
      //  message right after the identity message, we temporarily
      //  divert the message stream from session to ourselves.
      if (options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_XPUB) decoder.set_msg_sink(this);
    } else if (greeting.array()[version_pos] == 0) {
      //  ZMTP/1.0 framing.
      encoder = new_encoder(Config.out_batch_size.getValue(), null, 0);
      encoder.set_msg_source(session);

      decoder = new_decoder(Config.in_batch_size.getValue(), options.maxmsgsize, null, 0);
      decoder.set_msg_sink(session);
    } else {
      //  v1 framing protocol.
      encoder = new_encoder(Config.out_batch_size.getValue(), session, V1Protocol.VERSION);

      decoder =
          new_decoder(
              Config.in_batch_size.getValue(), options.maxmsgsize, session, V1Protocol.VERSION);
    }
    // Start polling for output if necessary.
    if (outsize == 0) io_object.set_pollout(handle);

    //  Handshaking was successful.
    //  Switch into the normal message flow.
    handshaking = false;

    return true;
  }