Mina message connector (NioDatagramConnector)

Mina abstract Polling connector (AbstractPollingIoConnector): http://donald-draper.iteye.com/blog/2378978
Mina packet listener NioDatagramAcceptor one (initialization, Io processor): http://donald-draper.iteye.com /blog/2379152
Mina message listener NioDatagramAcceptor II (send session message data, etc.): http://donald-draper.iteye.com/blog/2379228
Introduction:
    In the previous two articles, we saw the message listener/receiver NioDatagramAcceptor, let's review
    The message listener NioDatagramAcceptor has an internal registration queue registerQueue for storing address binding requests, a cancellation queue for storing address unbinding requests, and a Map-boundHandles for storing socket addresses and message channel mappings Relationship, session manager sessionRecycler, monitors the session connected to the Service, if the session expires, closes the expired session, a channel selector selector handles the read and write operation events of the message channel, and a listener thread acceptor is used to handle address binding and resolution. Binding, message channel read and write events, send session messages and destroy listener work. The message listener construction is mainly to initialize session configuration, IO event executor and open selector. For the message listener write operation, first obtain the session write request queue, calculate the maximum number of bytes sent by the session, and obtain the session write request buffer; if the write request is empty, poll a write request from the request queue, and then obtain the write request buffer and write request buffer. Request the destination socket address, and entrust the message channel associated with the session to send data; if there is too much buffer data or the writing is not successful, add a write request to the session request queue, and pay attention to the write event, otherwise unfollow the write event and empty the current write request of the session. Trigger the session to send events. To bind an address, first add the address binding request to the registration queue registerQueue, start the listener thread acceptor, wake up the selection operation, wait for the address binding to complete, and finally return the socket address set bound by the message channel.
    Listener thread Acceptor,First perform the timeout selection operation; process the address binding request, first poll the address binding request from the registration queue, traverse the binding request address set, open a message channel according to the bound socket address, configure the channel session and blocking mode, and bind The socket address, register the message channel read operation event OP_READ to the selector, add the socket address and the message channel mapping to boundHandles, notify the service monitor, the service has been opened, and trigger the fireServiceActivated event; if there is no message channel processing, clear the registration queue And cancel the queue, empty the listener thread; if there is a read and write event of the message channel ready after the selection operation, traverse the message channel ready for the read and write operation event, if it is a read event, accept the message channel data, if it is far away The end address is not empty, create a session, first obtain the message channel associated with the remote socket address from boundHandles, and obtain the remote socket address session from the session manager sessionRecycler for reuse. If it does not exist in the session manager, then according to Io The processor, the message channel and the remote socket address create a message session, set the session selection key, add the session to the session manager, monitor the session, initialize the session, build the session filter chain, and notify the Service listener that the session creation event fireSessionCreated occurs; if If it is a write event, schedule the session managed by the Service and add it to the refresh queue; process the refresh queue, poll the write request session from the refresh queue, obtain the session write request queue, and the session maximum read buffersize, get the current write request of the session, get the write request message, write the remote address of the request, send the byte sequence of the session message through the message channel associated with the session, the data is sent successfully, empty the current write request of the session, and trigger the session filter chain message sending Event fireMessageSent, otherwise set the session to re-focus on the write operation event. If the refresh session write request succeeds, but the session write request queue is not empty and not scheduled, the session will be rescheduled; to process the unbound address request queue, first cancel the queue, poll Address unbinding request, traverse the address unbinding request socket address set, remove the socket address from the socket and message channel mapping set boundHandles, close the message channel; notify the session managed by the service to be idle; if the Io processor is shutting down, destroy the message text listener.
Today, let's take a look at the message connector NioDatagramConnector, first look at the definition of the message connector interface:
/**
 * {@link IoConnector} for datagram transport (UDP/IP).
 *
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 */
public interface DatagramConnector extends IoConnector {
    /**
     * @return the default remote InetSocketAddress to connect to when no argument
     * is specified in {@link #connect()} method.
     Returns the default remote socket address
     * This method overrides the {@link IoConnector#getDefaultRemoteAddress()} method.
     */
    @Override
    InetSocketAddress getDefaultRemoteAddress();

    /**
     * @return the default configuration of the new FatagramSessions created by
     * this connect service.
     Get session configuration
     */
    @Override
    DatagramSessionConfig getSessionConfig();
    
    /**
     * Sets the default remote InetSocketAddress to connect to when no argument is
     * specified in {@link #connect()} method.
     * This method overrides the {@link IoConnector#setDefaultRemoteAddress(java.net.SocketAddress)} method.
     * Set the default remote socket address
     * @param remoteAddress The remote address to set
     */
    void setDefaultRemoteAddress(InetSocketAddress remoteAddress);
}

Let's look at the message connector NioDatagramConnector
/**
 * {@link IoConnector} for datagram transport (UDP/IP).
 *
 * @author [url=http://mina.apache.org]Apache MINA Project[/url]
 */
public final class NioDatagramConnector extends AbstractPollingIoConnector<NioSession, DatagramChannel> implements
DatagramConnector {

    /**
     * Creates a new instance.
     Create a message connector, default session configuration, use simple IO processor thread pool
     */
    public NioDatagramConnector() {
        super(new DefaultDatagramSessionConfig(), NioProcessor.class);
    }

    /**
     * Creates a new instance.
     * Different from the above, the number of simple IO processor thread pool threads is limited, that is, the number of IO processor instances
     * @param processorCount The number of IoProcessor instance to create
     */
    public NioDatagramConnector(int processorCount) {
        super(new DefaultDatagramSessionConfig(), NioProcessor.class, processorCount);
    }

    /**
     * Creates a new instance.
     * Multiple services share the same IO processor instance
     * @param processor The IoProcessor instance to use
     */
    public NioDatagramConnector(IoProcessor<NioSession> processor) {
        super(new DefaultDatagramSessionConfig(), processor);
    }

    /**
     * Constructor for {@link NioDatagramConnector} with default configuration which will use a built-in
     * thread pool executor to manage the given number of processor instances. The processor class must have
     * a constructor that accepts ExecutorService or Executor as its single argument, or, failing that, a
     * no-arg constructor.
     * Use a simple processor thread pool to limit the number of thread pool processing thread instances
     * @param processorClass the processor class.
     * @param processorCount the number of processors to instantiate.
     * @see SimpleIoProcessorPool#SimpleIoProcessorPool(Class, Executor, int, java.nio.channels.spi.SelectorProvider)
     * @since 2.0.0-M4
     */
    public NioDatagramConnector(Class<? extends IoProcessor<NioSession>> processorClass, int processorCount) {
        super(new DefaultDatagramSessionConfig(), processorClass, processorCount);
    }

    /**
     * Constructor for {@link NioDatagramConnector} with default configuration with default configuration which will use a built-in
     * thread pool executor to manage the default number of processor instances. The processor class must have
     * a constructor that accepts ExecutorService or Executor as its single argument, or, failing that, a
     * no-arg constructor. The default number of instances is equal to the number of processor cores
     * in the system, plus one.
     * The number of processor threads is the number of core threads + 1 similar to SimpleIoProcessorPool#SimpleIoProcessorPool
     * @param processorClass the processor class.
     * @see SimpleIoProcessorPool#SimpleIoProcessorPool(Class, Executor, int, java.nio.channels.spi.SelectorProvider)
     * @since 2.0.0-M4
     */
    public NioDatagramConnector(Class<? extends IoProcessor<NioSession>> processorClass) {
        super(new DefaultDatagramSessionConfig(), processorClass);
    }
}

The above result construction method of NioDatagramConnector is similar to the construction method of AbstractPollingIoConnector.
Let's look at other methods. These methods are very simple. You can understand them at a glance, and I won't talk much about them.
/**
 * {@inheritDoc}
 Create a message channel based on the socket address
 */
@Override
protected DatagramChannel newHandle(SocketAddress localAddress) throws Exception {
    //Open the message channel
    DatagramChannel ch = DatagramChannel.open();

    try {
        if (localAddress != null) {
            try {
	        //Bind the socket address
                ch.socket().bind(localAddress);
		//Set the default binding socket address
                setDefaultLocalAddress (localAddress);
            } catch (IOException ioe) {
                // Add some info regarding the address we try to bind to the
                // message
                String newMessage = "Error while binding on " + localAddress + "\n" + "original message : "
                        + ioe.getMessage();
                Exception e = new IOException(newMessage);
                e.initCause (ioe.getCause ());

                // and close the channel
                ch.close();

                throw e;
            }
        }
        return ch;
    } catch (Exception e) {
        // If we got an exception while binding the datagram,
        // we have to close it otherwise we will loose an handle
        ch.close();
        throw e;
    }
}

 /**
  * {@inheritDoc}
  Connect to the remote socket address and delegate directly to the message channel
  */
 @Override
 protected boolean connect(DatagramChannel handle, SocketAddress remoteAddress) throws Exception {
     handle.connect(remoteAddress);
     return true;
 }
/**
 * {@inheritDoc}
 Create a session
 */
@Override
protected NioSession newSession(IoProcessor<NioSession> processor, DatagramChannel handle) {
    NioSession session = new NioDatagramSession(this, handle, processor);
    session.getConfig().setAll(getSessionConfig());
    return session;
}
/**
@Override
 * {@inheritDoc}
 */
@Override
protected void init() throws Exception {
    // Do nothing
}
 /**
  * {@inheritDoc}
  */
 @Override
 protected void register(DatagramChannel handle, ConnectionRequest request) throws Exception {
     throw new UnsupportedOperationException();
 }

 /**
  * {@inheritDoc}
  */
 @Override
 protected int select(int timeout) throws Exception {
     return 0;
 }
/**
 * {@inheritDoc}
 */
@Override
protected void wakeup() {
    // Do nothing
}
/**
 * {@inheritDoc}
 Close the message channel
 */
@Override
protected void close(DatagramChannel handle) throws Exception {
    handle.disconnect();
    handle.close();
}
/**
 * {@inheritDoc}
 */
@Override
protected void destroy() throws Exception {
    // Do nothing
}
/**
 * {@inheritDoc}
 */
@Override
protected boolean finishConnect(DatagramChannel handle) throws Exception {
    throw new UnsupportedOperationException();
}
/**
 * {@inheritDoc}
 Get transport metadata
 */
@Override
public TransportMetadata getTransportMetadata() {
    return NioDatagramSession.METADATA;
}
/**
 * {@inheritDoc}
 */
@Override
public DatagramSessionConfig getSessionConfig() {
    return (DatagramSessionConfig) sessionConfig;
}
/**
 * {@inheritDoc}
 */
@Override
public InetSocketAddress getDefaultRemoteAddress() {
    return (InetSocketAddress) super.getDefaultRemoteAddress();
}
/**
 * {@inheritDoc}
 */
@Override
public void setDefaultRemoteAddress(InetSocketAddress defaultRemoteAddress) {
    super.setDefaultRemoteAddress(defaultRemoteAddress);
}
/**
 * {@inheritDoc}
 */
// Unused extension points.
@Override
protected Iterator<DatagramChannel> allHandles() {
    return Collections.emptyIterator();
}
/**
 * {@inheritDoc}
 */
@Override
protected ConnectionRequest getConnectionRequest(DatagramChannel handle) {
    throw new UnsupportedOperationException();
}
/**
 * {@inheritDoc}
 */
@Override
protected Iterator<DatagramChannel> selectedHandles() {
    return Collections.emptyIterator();
}

Summary:
Since the message connector is connectionless, the operations related to the selector are either not supported, or empty, or return an empty set; the connection operation directly delegates the message channel; bind the address, first open a message channel , and then the actual address binding is completed by the packet socket associated with the packet channel.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326412752&siteId=291194637