private void error() { assert (session != null); socket.event_disconnected(endpoint, handle); session.detach(); unplug(); destroy(); }
@Override public void in_event() { // If still handshaking, receive and process the greeting message. if (handshaking) if (!handshake()) return; assert (decoder != null); boolean disconnection = false; // If there's no data to process in the buffer... if (insize == 0) { // Retrieve the buffer and read as much data as possible. // Note that buffer can be arbitrarily large. However, we assume // the underlying TCP layer has fixed buffer size and thus the // number of bytes read will be always limited. inbuf = decoder.get_buffer(); insize = read(inbuf); inbuf.flip(); // Check whether the peer has closed the connection. if (insize == -1) { insize = 0; disconnection = true; } } // Push the data to the decoder. int processed = decoder.process_buffer(inbuf, insize); if (processed == -1) { disconnection = true; } else { // Stop polling for input if we got stuck. if (processed < insize) io_object.reset_pollin(handle); // Adjust the buffer. insize -= processed; } // Flush all messages the decoder may have produced. session.flush(); // An input error has occurred. If the last decoded message // has already been accepted, we terminate the engine immediately. // Otherwise, we stop waiting for socket events and postpone // the termination until after the message is accepted. if (disconnection) { if (decoder.stalled()) { io_object.rm_fd(handle); io_enabled = false; } else error(); } }
@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; }
@Override public void activate_in() { if (!io_enabled) { // There was an input error but the engine could not // be terminated (due to the stalled decoder). // Flush the pending message and terminate the engine now. decoder.process_buffer(inbuf, 0); assert (!decoder.stalled()); session.flush(); error(); return; } io_object.set_pollin(handle); // Speculative read. io_object.in_event(); }
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(); }