[size=large]Introduction介紹[/size]
Mina的縮寫意思是”Multipurpose Infrastructure for Network Applications(多用途網絡應用基礎設施)”,它用於開發高度可擴展和高性能網絡應用的網絡應用框架。在本文中,讓我們看看如何使用Apache Mina2.0.x來創建一個簡單的客戶端服務器端(c/s)應用。
[b]所需的JAR包[/b]
Apache Mina 2.0.x jars
slf4j-api.jar
slf4k-jdk14.jar
[size=large]服務端部分[/size]
對服務器端部分,我們需要使用MinaServer和MinaServerHandler兩個類。MinaServer類包含了主方法和名爲IoAcceptor的藉口來接受來自客戶端的進入連接,IoAcceptor用於向handler觸發相應的事件。 我們使用了兩個過濾器,第一個是LoggingFilter,用於記錄所有的事件,第二個是ProtocolCOdecFilter,用於轉換進入的ByteBuffer到報文的POJO。MinaServer的類代碼如下:
MinaServer.java
package net.javasight.mina;
/**
* @author javasight
*/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class MinaServer {
private static final int PORT = 1234;
public static void main(String[] args) throws IOException {
IoAcceptor acceptor = new NioSocketAcceptor();
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8"))));
acceptor.setHandler(new MinaServerHandler());
acceptor.getSessionConfig().setReadBufferSize(2048);
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
acceptor.bind(new InetSocketAddress(PORT));
}
}
接着我們創建一個名爲MinaServerHandler自定義handler,它包含了4個方法。第一個方法是sessionOpened在session打開後被調用, 它用於設置session的空閒時間。第二個方法是receiveMessage,用於接收由客戶端發送的消息。 其他兩個方法sessionIdle用於在session空閒10秒鐘後關閉該session,第四個方法exceptionCaught用於在異常發生時關閉session。MinaServerHandler類的代碼如下:
MinaServerHandler.java
package net.javasight.mina;
import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
/**
* @author javasight
*/
public class MinaServerHandler extends IoHandlerAdapter {
private final Logger logger = Logger.getLogger(getClass());
@Override
public void sessionOpened(IoSession session) {
// set idle time to 10 seconds
session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
session.setAttribute("Values: ");
}
@Override
public void messageReceived(IoSession session, Object message) {
logger.info("Message received in the server..");
logger.info("Message is: " + message.toString());
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) {
logger.info("Disconnecting the idle.");
// disconnect an idle client
session.close();
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
// close the connection on exceptional situation
session.close();
}
}
[size=large]客戶端部分[/size]
對於客戶端部分MinaClient和MinaClientHandler類被我們所使用。在MinaClient類中,IoConnector藉口用於與服務器端進行交互並向handler中觸發事件。 向服務端一樣,同樣的LoggingFilter、ProtocolCodecFilter也被使用了。名爲ConnectFuture接口被用於處理異步的連接請求。MinaClient類代碼如下:
MinaClient.java
package net.javasight.mina;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
/**
* @author javasight
*/
public class MinaClient {
private static final int PORT = 1234;
public static void main(String[] args) throws IOException,
InterruptedException {
IoConnector connector = new NioSocketConnector();
connector.getSessionConfig().setReadBufferSize(2048);
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast(
"codec",
new ProtocolCodecFilter(new TextLineCodecFactory(Charset
.forName("UTF-8"))));
connector.setHandler(new MinaClientHandler("Hello Server.."));
ConnectFuture future = connector.connect(new InetSocketAddress(
"172.108.0.12", PORT));
future.awaitUninterruptibly();
if (!future.isConnected()) {
return;
}
IoSession session = future.getSession();
session.getConfig().setUseReadOperation(true);
session.getCloseFuture().awaitUninterruptibly();
System.out.println("After Writing");
connector.dispose();
}
}
對於handler,像服務器部分一樣,sessionOpened、messageReceived和exceptionCaught方法同樣被使用了。MinaClientHandler類代碼如下:
MinaClientHandler.java
package net.javasight.mina;
import org.apache.log4j.Logger;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
/**
* @author giftsam
*/
public class MinaClientHandler extends IoHandlerAdapter {
private final Logger logger = Logger.getLogger(getClass());
private final String values;
private boolean finished;
public MinaClientHandler(String values) {
this.values = values;
}
public boolean isFinished() {
return finished;
}
@Override
public void sessionOpened(IoSession session) {
session.write(values);
}
@Override
public void messageReceived(IoSession session, Object message) {
logger.info("Message received in the client..");
logger.info("Message is: " + message.toString());
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
session.close();
}
}
現在是對之前代碼進行測試的時候了,首先MinaServer應該先被啓動然後啓動MinaClient,代碼的輸出類似如下:
[b]MinaServer – 輸出[/b]
4412 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - CREATED
4412 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - OPENED
4449 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - RECEIVED: HeapBuffer[pos=0 lim=15 cap=2048: 48 65 6C 6C 6F 20 53 65 72 76 65 72 2E 2E 0A]
0 [NioProcessor-2] INFO net.javasight.mina.MinaServerHandler - Message received in the server..
1 [NioProcessor-2] INFO net.javasight.mina.MinaServerHandler - Message is: Hello Server..
14453 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - IDLE
10001 [NioProcessor-2] INFO net.javasight.mina.MinaServerHandler - Disconnecting the idle.
14457 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - CLOSED
[b]MinaClient – 輸出[/b]
297 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - CREATED
297 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - OPENED
325 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - SENT: HeapBuffer[pos=0 lim=0 cap=0: empty]
10334 [NioProcessor-2] INFO org.apache.mina.filter.logging.LoggingFilter - CLOSED
After Writing
這就是所有內容。我希望本文清晰的解釋了使用Apache Mina 2.0.x的簡單的客戶端/服務器應用。