private void unplug() { assert (plugged); plugged = false; // Cancel all fd subscriptions. if (io_enabled) { io_object.rm_fd(handle); io_enabled = false; } // Disconnect from I/O threads poller object. io_object.unplug(); // Disconnect from session object. if (encoder != null) encoder.set_msg_source(null); if (decoder != null) decoder.set_msg_sink(null); session = null; }
@Override public int push_msg(Msg msg_) { assert (options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_XPUB); // The first message is identity. // Let the session process it. int rc = session.push_msg(msg_); assert (rc == 0); // Inject the subscription message so that the ZMQ 2.x peer // receives our messages. msg_ = new Msg(1); msg_.put((byte) 1); rc = session.push_msg(msg_); session.flush(); // Once we have injected the subscription message, we can // Divert the message flow back to the session. assert (decoder != null); decoder.set_msg_sink(session); return rc; }
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; }