Apache Mina – 簡單的客戶端/服務端應用示例

轉自http://javasight.net/2011/05/simple-client-server-application-using-mina/

[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的簡單的客戶端/服務器應用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章