The core of the entire framework of several packages are: Org.apache.mina.core.service, org.apache.mina.core.session, Org.apache.mina.core.polling and Org.apache.mina.transport.socket.
This article first looks at Org.apache.mina.core.service. The first interface to say is Ioservice, which is the base interface for all Ioacceptor and ioconnector. What information do we need to focus on for a ioservice? 1) The underlying metadata information transportmetadata, such as the underlying network service provider (NIO,ARP,RXTX, etc.), 2) when a new session is created through this service, the default configuration of the new session is Iosessionconfig. 3) All sessions managed by this service. 4) Listener (Ioservicelistener) corresponding to the event generated by this service. 5) Handle all connected processors (Iohandler) managed by this service. 6) Each session has a filter chain (Iofilterchain), and each filter chain is built by its corresponding iofilterchainbuilder. 7) Because this service manages a series of sessions, messages can be broadcast to all sessions, and the result is a writefuture set, which is a data structure that represents the expected results in the future. 8) The data related to the session (Iosession) created by the service is provided through Iosessiondatastructurefactory. 9) There is a write buffer queue when sending a message. 10) The idle state of the service has three kinds: The reading end is idle, the writing end is idle, the double end is idle. 11) Also provide some statistical information of the service, such as time, data volume, etc.
Ioservice This service is an abstraction for both the server-side accept connection and the client-initiated connection behavior.
Again, from the server, Ioacceptor is Ioservice's sub-interface, which is used to bind to the specified IP and port to receive connection requests from the client, while the fire corresponding client connection successfully received/canceled/failed events to their own iohandle to handle. When the server-side accpetor is unbound from the previously bound IP and port, the default is that all client sessions are closed, which typically occurs when the server is hung up, and the client receives a prompt to close the connection. The two most important methods of this interface are bind () and Unbind (), and when these two methods are called, the connection accept thread on the server starts or shuts down.
Then take a look at the Client connection initiator interface Ioconnector, its function and ioacceptor basic correspondence, it is used to try to connect to the server specified IP and port, while the fire corresponding client connection event to their own iohandle to handle. When the Connet method is called, the thread used to connect to the server starts, and the thread stops when all connection attempts are ended. The time-out for the attempt to connect can be set by itself. The result of the Connect method is Connectfuture, which is similar to the previous writefuture, and there will be an application that specifically says this pattern later.
The front ioacceptor and Ioconnector are like two servants in charge of shaking hands, and the interface that really represents the actual I/O operation of the session is Ioprocessor, which continues to encapsulate the Java NIO framework of the existing reactor schema architecture. Its generic parameter indicates the type of session it can handle. One of the most important methods in the interface, add is used to join the specified session to this processor, which is responsible for all I/O operations related to this session. Because the write operation has a write request queue,flush is used to enforce the data for the write request queue of the specified session. The Remove method is used to remove and close the specified session from this processor, so that the connection associated with the session is closed and all related resources are freed. The Updatetrafficmask method is used to control the I/O behavior of the session, such as whether read /write is allowed.
Then say the Iohandle interface, all I/O events in the Mina are handled through this interface, these events are the above mentioned I/O Processor sent out, one thing to note is the same I/O Processor The thread is responsible for processing multiple sessions . This includes handling of the following events:
Public InterfaceIohandler {voidSessioncreated (iosession session) throws Exception;//Session Creation voidSessionopened (iosession session) throws Exception;//The biggest difference between opening a session and sessioncreated is that it is called from another thread voidSessionclosed (iosession session) throws Exception;//session end, called when connection is closed voidSessionidle (iosession session, Idlestatus status) throws Exception;//Session Idle voidExceptioncaught (iosession session, Throwable cause) throws Exception;//exception capture, Mina will automatically close this connection voidMessagereceived (iosession session, Object message) throws Exception;//Receive Message voidMessagesent (iosession session, Object message) throws Exception;//Send Message}
Iohandleradapter did not say, simply the Iohandler using the adapter mode encapsulation, so that the specific Iohandler subclasses inherit from it, so that you can need to own the event processing autonomy.
Take a look at the Ioservicelistener interface, which is used to listen for ioservice related events.
Public InterfaceIoservicelistenerextendsEventListener {voidserviceactivated (Ioservice Service)throwsException;//A new service has been activated voidServiceidle (ioservice service, Idlestatus idlestatus)throwsException;//Service Idle voidservicedeactivated (Ioservice Service)throwsException;//Suspend a service voidSessioncreated (iosession session)throwsException;//create a new session voidSessiondestroyed (iosession session)throwsException;//destroy a new session}
Ioservicelistenersupport class is responsible for the above Ioservice and its corresponding Ioservicelistener packaging together for management. Here is its member variable:
Private FinalIoservice Service; Private Finallist<ioservicelistener> listeners =NewCopyonwritearraylist<ioservicelistener>(); Private FinalConcurrentmap<long, iosession> managedsessions =NewConcurrenthashmap<long, iosession> ();//managed session set (which is actually the set of sessions managed by the service) Private FinalMap<long, iosession> readonlymanagedsessions = Collections.unmodifiablemap (managedsessions);//read-only version of the above session set Private FinalAtomicboolean activated =NewAtomicboolean ();//whether the managed service is active
The activation event is described in session creation as an example:
Public voidFiresessioncreated (iosession session) {BooleanFirstsession =false; //If the service type is connector, then the client's connection service if(Session.getservice ()instanceofioconnector) { //Lock the currently established session set synchronized(managedsessions) {//see if the session set managed by the service is emptyFirstsession =Managedsessions.isempty (); } } if(Managedsessions.putifabsent (Long.valueof (Session.getid ()), session)! =NULL) {//If already registered, ignore. return; } //first Connection session, fire a virtual service activation event if(firstsession) {fireserviceactivated (); } //event handling for call filtersSession.getfilterchain (). firesessioncreated ();//Session CreationSession.getfilterchain (). firesessionopened ();//Session Open intManagedsessioncount =managedsessions.size (); //number of sessions managed by Statistics if(Managedsessioncount >Largestmanagedsessioncount) {Largestmanagedsessioncount=Managedsessioncount; } Cumulativemanagedsessioncount++; //event handler function for Call listener for(Ioservicelistener listener:listeners) {Try{listener.sessioncreated (session); } Catch(Throwable e) {exceptionmonitor.getinstance (). Exceptioncaught (e); } } }
One place to note here is to disconnect the session, set a listening lock, and then release the lock until all the connection sessions have been closed.
Private voiddisconnectsessions () {//Ensure that the service type is Ioacceptor if(! (Serviceinstanceofioacceptor)) { return; } //Ioacceptor is set to close all connection sessions when the service fails if(!( (ioacceptor) service). Iscloseondeactivation ()) { return; } Object Lock=NewObject ();//Monitor LockIofuturelistener<iofuture> listener =NewLocknotifyinglistener (lock); for(Iosession s:managedsessions.values ()) {//add a listener to the close action for each sessions.close (). AddListener (listener); } Try { synchronized(lock) {//The managed session is not all over yet, holding the lock waiting while(!Managedsessions.isempty ()) {lock.wait (500); } } } Catch(Interruptedexception IE) {//ignored } } Private Static classLocknotifyinglistenerImplementsIofuturelistener<iofuture> { Private FinalObject Lock; PublicLocknotifyinglistener (Object lock) { This. Lock =lock; } Public voidOperationcomplete (iofuture future) {synchronized(lock) {lock.notifyall (); } } }
Phinecos (The Cave of the Chamber scattered people)
Source: http://phinecos.cnblogs.com/
This article is copyright to the author and the blog Garden is shared, welcome reprint, but please keep this paragraph statement, and in the article page obvious location to the original link.
Mina2.0 Framework Source code Analysis (I.)