開發環境:
System:Windows
JavaSDK:1.6
IDE:eclipse、MyEclipse 6.6
開發依賴庫:
Jdk1.4+、mina-core-2.0.4.jar、slf4j-api-1.5.11.jar、slf4j-log4j12-1.5.11.jar
Email:hoojo_@126.com
前不久用Socket寫的聊天程序,主要是手機端程序通過Socket連接服務器端的ServerSocket,然后服務器端根據客戶端發送過來統一規范的報文。進行解析再用smack框架轉發到openfire服務器,最后由openfire服務器向客戶端程序發送聊天信息。
最近發現socket服務器資源消耗比較大。我是采用阻塞式多線程通信方式,這種方式會造成大量的服務器資源浪費、長期的占用服務器的CUP調度權,並且會長時間阻塞程序,等待客戶端連接、發送消息等。
為了解決上面的狀況,Apache MiNa能很好的解決這個問題。Mina采用的是非阻塞式、單線程、NIO通信方式。
非阻塞式通信的思想是:讓一個線程同時完成多件事,這個線程會利用完成這件事的空余時間去完成另一件事,一刻也不閑着。這個線程同時也會不斷監控每件事情中需要處理時間的發生,發生一個就處理一件,然后繼續監聽各自事情。
一、介紹
首先,Mina是個什么東西?看下官方網站(http://mina.apache.org/)對它的解釋:
Apache的Mina(Multipurpose Infrastructure Networked Applications)是一個網絡應用框架,可以幫助用戶開發高性能和高擴展性的網絡應用程序;它提供了一個抽象的、事件驅動的異步API,使Java NIO在各種傳輸協議(如TCP/IP,UDP/IP協議等)下快速高效開發。
Apache Mina也稱為:
NIO框架
網絡套接字(networking socket)類庫
事件驅動的異步API(注意:在JDK7中也新增了異步API)
總之:我們簡單理解它是一個封裝底層IO操作,提供高級操作API的通訊框架!
二、服務器端編碼工作
第一步:
使用Apache MiNa框架,你需要下載jar
下載地址:http://mina.apache.org/dyn/closer.cgi/mina/2.0.4/apache-mina-2.0.4-bin.zip
你需要添加jar如下
如果你使用日志,需要添加日志配置文件log4j.properties
第二步:
編寫通信要用的解碼工廠和編碼器、解碼器類,代碼如下
package com.hoo.mina.code.factory;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFactory;import org.apache.mina.filter.codec.ProtocolDecoder;import org.apache.mina.filter.codec.ProtocolEncoder;import com.hoo.mina.code.CharsetDecoder;import com.hoo.mina.code.CharsetEncoder;/*** <b>function:</b> 字符編碼、解碼工廠類,編碼過濾工廠* @author hoojo* @createDate 2012-6-26 下午01:08:50* @file CharsetCodecFactory.java* @package com.hoo.mina.code.factory* @project ApacheMiNa* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class CharsetCodecFactory implements ProtocolCodecFactory {@Overridepublic ProtocolDecoder getDecoder(IoSession session) throws Exception {return new CharsetDecoder();}@Overridepublic ProtocolEncoder getEncoder(IoSession session) throws Exception {return new CharsetEncoder();}}解碼類
package com.hoo.mina.code;import java.nio.charset.Charset;import org.apache.log4j.Logger;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolDecoder;import org.apache.mina.filter.codec.ProtocolDecoderOutput;/*** <b>function:</b> 字符解碼* @author hoojo* @createDate 2012-6-26 上午11:14:18* @file CharsetDecoder.java* @package com.hoo.mina.code* @project ApacheMiNa* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class CharsetDecoder implements ProtocolDecoder {private final static Logger log = Logger.getLogger(CharsetDecoder.class);private final static Charset charset = Charset.forName("UTF-8");// 可變的IoBuffer數據緩沖區private IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);@Overridepublic void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {log.info("#########decode#########");// 如果有消息while (in.hasRemaining()) {// 判斷消息是否是結束符,不同平台的結束符也不一樣;// windows換行符(\r\n)就認為是一個完整消息的結束符了; UNIX 是\n;MAC 是\rbyte b = in.get();if (b == '\n') {buff.flip();byte[] bytes = new byte[buff.limit()];buff.get(bytes);String message = new String(bytes, charset);buff = IoBuffer.allocate(100).setAutoExpand(true);// 如果結束了,就寫入轉碼后的數據out.write(message);//log.info("message: " + message);} else {buff.put(b);}}}@Overridepublic void dispose(IoSession session) throws Exception {log.info("#########dispose#########");log.info(session.getCurrentWriteMessage());}@Overridepublic void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {log.info("#########完成解碼#########");}}上面的decode方法是解碼方法,它主要是把讀取到數據中的換行符去掉。因為在mina通信協議中以換行符為結束符,如果不定義結束符那么程序會在那里一直等待下一條發送的數據。
這里用到了IoBuffer,MiNa中傳輸的所有二進制信息都存放在IoBuffer中,IoBuffer是對Java NIO中ByteBuffer的封裝(Mina2.0以前版本這個接口也是ByteBuffer),提供了更多操作二進制數據,對象的方法,並且存儲空間可以自增長,用起來非常方便;簡單理解,它就是個可變長度的byte字節數組!
1. static IoBuffer allocate(int capacity,boolean useDirectBuffer)
創建IoBuffer實例,第一個參數指定初始化容量,第二個參數指定使用直接緩沖區還是JAVA 內存堆的緩存區,默認為false。
2.IoBuffer setAutoExpand(boolean autoExpand)
這個方法設置IoBuffer 為自動擴展容量,也就是前面所說的長度可變,那么可以看出長度可變這個特性默認是不開啟的。
3. IoBuffer flip()
limit=position, position=0,重置mask,為了讀取做好准備,一般是結束buffer操作,將buffer寫入輸出流時調用;這個必須要調用,否則極有可能position!=limit,導致position后面沒有數據;每次寫入數據到輸出流時,必須確保position=limit。
4. IoBuffer clear()與IoBuffer reset()
clear:limit=capacity , position=0,重置mark;它是不清空數據,但從頭開始存放數據做准備---相當於覆蓋老數據。
reset就是清空數據
5. int remaining()與boolean hasRemaining()
這兩個方法一般是在調用了flip方法后使用的,remaining()是返回limt-position的值!hasRemaining()則是判斷當前是否有數據,返回position < limit的boolean值!
編碼類
package com.hoo.mina.code;import java.nio.charset.Charset;import org.apache.log4j.Logger;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolEncoder;import org.apache.mina.filter.codec.ProtocolEncoderOutput;import org.apache.mina.filter.codec.textline.LineDelimiter;/*** <b>function:</b> 字符編碼* @author hoojo* @createDate 2012-6-26 上午11:32:05* @file CharsetEncoder.java* @package com.hoo.mina.code* @project ApacheMiNa* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class CharsetEncoder implements ProtocolEncoder {private final static Logger log = Logger.getLogger(CharsetEncoder.class);private final static Charset charset = Charset.forName("UTF-8");@Overridepublic void dispose(IoSession session) throws Exception {log.info("#############dispose############");}@Overridepublic void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception {log.info("#############字符編碼############");IoBuffer buff = IoBuffer.allocate(100).setAutoExpand(true);buff.putString(message.toString(), charset.newEncoder());// put 當前系統默認換行符buff.putString(LineDelimiter.DEFAULT.getValue(), charset.newEncoder());// 為下一次讀取數據做准備buff.flip();out.write(buff);}}
第三步:
編寫IoHandler實現類代碼,IoHander這里是Io讀寫的事件驅動類,這里的Io操作都會觸發里面的事件。你所有的業務邏輯都應當在這個類中完成。
package com.hoo.mina.server.message;import java.text.SimpleDateFormat;import java.util.Collection;import java.util.Date;import org.apache.mina.core.future.CloseFuture;import org.apache.mina.core.future.IoFuture;import org.apache.mina.core.future.IoFutureListener;import org.apache.mina.core.service.IoHandler;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/*** <b>function:</b> 處理服務器端消息* @author hoojo* @createDate 2012-6-26 下午01:12:34* @file ServerMessageHandler.java* @package com.hoo.mina.server.message* @project ApacheMiNa* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class ServerMessageHandler implements IoHandler {private final static Logger log = LoggerFactory.getLogger(ServerMessageHandler.class);@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {log.info("服務器發生異常: {}", cause.getMessage());}@Overridepublic void messageReceived(IoSession session, Object message) throws Exception {log.info("服務器接收到數據: {}", message);String content = message.toString();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");String datetime = sdf.format(new Date());log.info("轉發 messageReceived: " + datetime + "\t" + content);// 拿到所有的客戶端SessionCollection<IoSession> sessions = session.getService().getManagedSessions().values();// 向所有客戶端發送數據for (IoSession sess : sessions) {sess.write(datetime + "\t" + content);}}@Overridepublic void messageSent(IoSession session, Object message) throws Exception {log.info("服務器發送消息: {}", message);}@Overridepublic void sessionClosed(IoSession session) throws Exception {log.info("關閉當前session:{}#{}", session.getId(), session.getRemoteAddress());CloseFuture closeFuture = session.close(true);closeFuture.addListener(new IoFutureListener<IoFuture>() {public void operationComplete(IoFuture future) {if (future instanceof CloseFuture) {((CloseFuture) future).setClosed();log.info("sessionClosed CloseFuture setClosed-->{},", future.getSession().getId());}}});}@Overridepublic void sessionCreated(IoSession session) throws Exception {log.info("創建一個新連接:{}", session.getRemoteAddress());session.write("welcome to the chat room !");}@Overridepublic void sessionIdle(IoSession session, IdleStatus status) throws Exception {log.info("當前連接{}處於空閑狀態:{}", session.getRemoteAddress(), status);}@Overridepublic void sessionOpened(IoSession session) throws Exception {log.info("打開一個session:{}#{}", session.getId(), session.getBothIdleCount());}}sessionCreated:當一個新的連接建立時,由I/O processor thread調用;
sessionOpened:當連接打開是調用;
messageReceived: 當接收了一個消息時調用;
messageSent:當一個消息被(IoSession#write)發送出去后調用;
sessionIdle:當連接進入空閑狀態時調用;
sessionClosed:當連接關閉時調用;
exceptionCaught:實現IoHandler的類拋出異常時調用;
一般情況下,我們最關心的只有messageReceived方法,接收消息並處理,然后調用IoSession的write方法發送出消息!(注意:這里接收到的消息都是Java對象,在IoFilter中所有二進制數據都被解碼)一般情況下很少有人實現IoHandler接口,而是繼承它的一個實現類IoHandlerAdapter,這樣不用覆蓋它的7個方法,只需要根據具體需求覆蓋其中的幾個方法就可以!
Iohandler的7個方法其實是根據session的4個狀態值間變化來調用的:
Connected:會話被創建並使用;
Idle:會話在一段時間(可配置)內沒有任何請求到達,進入空閑狀態;
Closing:會話將被關閉(剩余message將被強制flush);
Closed:會話被關閉;
狀態轉換圖如下:
第四步:
編寫server啟動類,bind端口、設置編碼過程和核心業務處理器
package com.hoo.mina.server;import java.io.IOException;import java.net.InetSocketAddress;import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.transport.socket.SocketAcceptor;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;import com.hoo.mina.code.factory.CharsetCodecFactory;import com.hoo.mina.server.message.ServerMessageHandler;/*** <b>function:</b> 服務器啟動類* @author hoojo* @createDate 2012-6-29 下午07:11:00* @file MinaServer.java* @package com.hoo.mina.server* @project ApacheMiNa* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class MinaServer {private SocketAcceptor acceptor;public MinaServer() {// 創建非阻塞的server端的Socket連接acceptor = new NioSocketAcceptor();}public boolean start() {DefaultIoFilterChainBuilder filterChain = acceptor.getFilterChain();// 添加編碼過濾器 處理亂碼、編碼問題filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));/*LoggingFilter loggingFilter = new LoggingFilter();loggingFilter.setMessageReceivedLogLevel(LogLevel.INFO);loggingFilter.setMessageSentLogLevel(LogLevel.INFO);// 添加日志過濾器filterChain.addLast("loger", loggingFilter);*/// 設置核心消息業務處理器acceptor.setHandler(new ServerMessageHandler());// 設置session配置,30秒內無操作進入空閑狀態acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);try {// 綁定端口3456acceptor.bind(new InetSocketAddress(3456));} catch (IOException e) {e.printStackTrace();return false;}return true;}public static void main(String[] args) {MinaServer server = new MinaServer();server.start();}}上面的代碼主要完成啟動參數的設置,如端口、session參數;消息核心業務處理器,這個比較關鍵,我們所有的業務都要在這里完成;然后就是日志、編碼過濾器,我們可以對發送或接收到的消息進行處理、編碼操作,在網絡中傳遞數據都是字節流傳遞的,我們要獲取消息必須把二進制的字節流轉換的字符串來處理,所以這個也是必須的;同時你還可以對服務器添加日志過濾器,來顯示日志。
這樣服務器端程序就已經完成,你可以用socket或mina client等方式連接服務器,進行通信。
啟動服務器,在瀏覽器中輸入http://localhost:3456 這里的服務器綁定的端口是3456
然后你在控制台中可以看到當前瀏覽器的一些基本信息,如果你看到這些信息就表示你服務器代碼編寫沒有什么問題,應該可以成功建立客戶端連接。信息如下:
2012-08-01 09:55:56,046 INFO [com.hoo.mina.server.message.ServerMessageHandler:75-NioProcessor-1] - 創建一個新連接:/127.0.0.1:25422012-08-01 09:55:56,046 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符編碼############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:86-NioProcessor-1] - 打開一個session:3#02012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-1] - 服務器發送消息: welcome to the chat room !2012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-1] - #########decode#########2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服務器接收到數據: GET / HTTP/1.12012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 轉發 messageReceived: 2012-08-01 09:55:56 GET / HTTP/1.12012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符編碼############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服務器接收到數據: Host: localhost:34562012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 轉發 messageReceived: 2012-08-01 09:55:56 Host: localhost:34562012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符編碼############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服務器接收到數據: User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.12012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 轉發 messageReceived: 2012-08-01 09:55:56 User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.12012-08-01 09:55:56,062 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-1] - #############字符編碼############2012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-1] - 服務器接收到數據: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.82012-08-01 09:55:56,062 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-1] - 轉發 messageReceived: 2012-08-01 09:55:56 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8其他內容省略……
三、客戶端編碼工作
第一步:
編寫客戶端消息核心處理業務類型,消息處理器
package com.hoo.mina.client.message;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IoSession;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/*** <b>function:</b> 客戶端消息處理類* @author hoojo* @createDate 2012-6-29 下午07:24:22* @file ClientMessageHandlerAdapter.java* @package com.hoo.mina.client.message* @project ApacheMiNa* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class ClientMessageHandlerAdapter extends IoHandlerAdapter {private final static Logger log = LoggerFactory.getLogger(ClientMessageHandlerAdapter.class);public void messageReceived(IoSession session, Object message) throws Exception {String content = message.toString();log.info("client receive a message is : " + content);}public void messageSent(IoSession session , Object message) throws Exception{log.info("messageSent 客戶端發送消息:" + message);}@Overridepublic void exceptionCaught(IoSession session, Throwable cause) throws Exception {log.info("服務器發生異常: {}", cause.getMessage());}}這里我們沒有實現IoHandler這個接口,而是繼承了IoHandlerAdapter這類,覆蓋了messageReceived、messageSent這兩個方法。IoHandlerAdapter是IoHandler接口的一個實現,我們這里沒有必要實現IoHandler的所有方法。
第二步:
編寫連接服務器的代碼,設置核心消息處理器
package com.hoo.mina.client;import java.net.InetSocketAddress;import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;import org.apache.mina.core.future.CloseFuture;import org.apache.mina.core.future.ConnectFuture;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.transport.socket.SocketConnector;import org.apache.mina.transport.socket.nio.NioSocketConnector;import com.hoo.mina.client.message.ClientMessageHandlerAdapter;import com.hoo.mina.code.factory.CharsetCodecFactory;/*** <b>function:</b> mina客戶端* @author hoojo* @createDate 2012-6-29 下午07:28:45* @file MinaClient.java* @package com.hoo.mina.client.message* @project ApacheMiNa* @blog http://blog.csdn.net/IBM_hoojo* @email hoojo_@126.com* @version 1.0*/public class MinaClient {private SocketConnector connector;private ConnectFuture future;private IoSession session;public boolean connect() {// 創建一個socket連接connector = new NioSocketConnector();// 設置鏈接超時時間connector.setConnectTimeoutMillis(3000);// 獲取過濾器鏈DefaultIoFilterChainBuilder filterChain = connector.getFilterChain();// 添加編碼過濾器 處理亂碼、編碼問題filterChain.addLast("codec", new ProtocolCodecFilter(new CharsetCodecFactory()));/*// 日志LoggingFilter loggingFilter = new LoggingFilter();loggingFilter.setMessageReceivedLogLevel(LogLevel.INFO);loggingFilter.setMessageSentLogLevel(LogLevel.INFO);filterChain.addLast("loger", loggingFilter);*/// 消息核心處理器connector.setHandler(new ClientMessageHandlerAdapter());// 連接服務器,知道端口、地址future = connector.connect(new InetSocketAddress(3456));// 等待連接創建完成future.awaitUninterruptibly();// 獲取當前sessionsession = future.getSession();return true;}public void setAttribute(Object key, Object value) {session.setAttribute(key, value);}public void send(String message) {session.write(message);}public boolean close() {CloseFuture future = session.getCloseFuture();future.awaitUninterruptibly(1000);connector.dispose();return true;}public SocketConnector getConnector() {return connector;}public IoSession getSession() {return session;}}
第三步:
完成啟動、在控制台輸入你發送的內容
package com.hoo.mina.client.main;
import java.util.Scanner;
import com.hoo.mina.client.MinaClient;
/**
* <b>function:</b> 運行客戶端程序
* @author hoojo
* @createDate 2012-6-29 下午07:36:44
* @file RunClient.java
* @package com.hoo.mina.client.main
* @project ApacheMiNa
* @blog http://blog.csdn.net/IBM_hoojo
* @email hoojo_@126.com
* @version 1.0
*/
public class RunClient {
public static void main(String[] args) {
MinaClient client = new MinaClient();
if (client.connect()) {
client.send("連接服務器成功!");
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
client.send(scanner.next());
}
}
}
}
啟動服務器,運行客戶端程序可以看到控制台:
2012-08-01 10:01:15,953 INFO [com.hoo.mina.code.CharsetEncoder:34-main] - #############字符編碼############
2012-08-01 10:01:15,953 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:01:15,953 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:25-NioProcessor-2] - client receive a message is : welcome to the chat room !
2012-08-01 10:01:15,984 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:29-NioProcessor-2] - messageSent 客戶端發送消息:連接服務器成功!
2012-08-01 10:01:15,984 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:01:15,984 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:25-NioProcessor-2] - client receive a message is : 2012-08-01 10:01:15
服務器控制台:
2012-08-01 10:01:15,921 INFO [com.hoo.mina.server.message.ServerMessageHandler:75-NioProcessor-2] - 創建一個新連接:/192.168.8.22:2644
2012-08-01 10:01:15,937 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-2] - #############字符編碼############
2012-08-01 10:01:15,937 INFO [com.hoo.mina.server.message.ServerMessageHandler:86-NioProcessor-2] - 打開一個session:1#0
2012-08-01 10:01:15,937 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-2] - 服務器發送消息: welcome to the chat room !
2012-08-01 10:01:15,984 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:01:15,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-2] - 服務器接收到數據: 連接服務器成功!
2012-08-01 10:01:15,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-2] - 轉發 messageReceived: 2012-08-01 10:01:15 連接服務器成功!
2012-08-01 10:01:15,984 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-2] - #############字符編碼############
2012-08-01 10:01:15,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-2] - 服務器發送消息: 2012-08-01 10:01:15 連接服務器成功!
2012-08-01 10:01:45,984 INFO [com.hoo.mina.server.message.ServerMessageHandler:81-NioProcessor-2] - 當前連接/192.168.8.22:2644處於空閑狀態:both idle
在客戶端控制台輸入聊天內容
hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetEncoder:34-main] - #############字符編碼############
2012-08-01 10:03:49,093 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:29-NioProcessor-2] - messageSent 客戶端發送消息:hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:03:49,093 INFO [com.hoo.mina.client.message.ClientMessageHandlerAdapter:25-NioProcessor-2] - client receive a message is : 2012-08-01 10:03:49
服務器端接收到內容
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetDecoder:31-NioProcessor-2] - #########decode#########
2012-08-01 10:03:49,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:38-NioProcessor-2] - 服務器接收到數據: hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:43-NioProcessor-2] - 轉發 messageReceived: 2012-08-01 10:03:49 hello,MiNaChat~!
2012-08-01 10:03:49,093 INFO [com.hoo.mina.code.CharsetEncoder:34-NioProcessor-2] - #############字符編碼############
2012-08-01 10:03:49,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:55-NioProcessor-2] - 服務器發送消息: 2012-08-01 10:03:49 hello,MiNaChat~!
2012-08-01 10:04:19,093 INFO [com.hoo.mina.server.message.ServerMessageHandler:81-NioProcessor-2] - 當前連接/192.168.8.22:2644處於空閑狀態:both idle