完成的目标:服务器接受到客户端的信息后作出一个反应(发送一条信息),客户端获得这条信息(同一个客户端可以不停的发送数据请求)。
上午的目标竟然在下午才能够完成:
先来看看我们的服务器端(server):
//代码其实很简单,但是我们一定要弄懂原理(越简单的代码我们要越小心)
public class MinaTimeServer
{
private static final int PORT = 9123;
public static void main( String[] args ) throws IOException
{
IoAcceptor acceptor = new NioSocketAcceptor();//new 一个TCP传输的Acceptor(相当于SeverSocket)
//filter非常重要,且在server和client两边我们都要设定正确了,否则,MINA就他妈的是一个傻子(不给开发者任何消息),还有MINA这种公用框架尽然要log4j。
//一个单用型公用包不应该有log日志打印系统的,所有的公用包的信息都要用exception抛出才对
acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
acceptor.getFilterChain().addLast( "codec",
new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));//要特别的注意了,这个设定一定要和client端的相对应。
acceptor.setHandler( new TimeServerHandler() );//设定用户逻辑处理类
acceptor.getSessionConfig().setReadBufferSize( 2048 );//设定读取数据容器大小
acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
acceptor.bind( new InetSocketAddress(PORT) );
}
}
当然了,这段代码是抄袭过来的。刚开始还挺佩服写这个博客的人,后来在MINA官网上发现了这段代码,瞬间我就有一种莫名的奇怪感遍布全身。
有了上面的启动代码后,我们还需要一个非常重要的逻辑处理类:
public class TimeServerHandler extends IoHandlerAdapter
{
@Overridepublic void exceptionCaught( IoSession session, Throwable cause ) throws Exception{cause.printStackTrace();}
@Overridepublic void messageReceived( IoSession session, Object message ) throws Exception{//接受数据的地方String str = message.toString();if( str.trim().equalsIgnoreCase("quit") ) {session.close();return;}Date date = new Date();System.out.println(date.toString());session.write( date.toString() );//此方法会触发下面的messageSent方法System.out.println("Message written...");System.out.println("Message is: "+str);}
@Overridepublic void sessionIdle( IoSession session, IdleStatus status ) throws Exception{System.out.println( "IDLE " + session.getIdleCount( status ));}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
//发送数据的地方
System.out.println("message sent: "+message.toString());super.messageSent(session, message);
}
}
恩,上面就完成了一个Sever端的服务提供方了。下面我们来构造我们自己的client端:
public class Client {
public static void main(String args[]){
IoConnector connector = new NioSocketConnector();connector.setConnectTimeoutMillis(30000);connector.getFilterChain().addLast(//这个地方注意了,其设定一定要和服务器的编码数据相对应"codec",new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));ClientHandler ch = new ClientHandler("nihao");connector.setHandler(ch);connector.getSessionConfig().setReadBufferSize(1024);connector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 100);connector.getSessionConfig().setUseReadOperation(true);ConnectFuture cf = connector.connect(new InetSocketAddress("localhost", 9123));cf.awaitUninterruptibly();IoSession is = cf.getSession();System.out.println("connected is over!");// while(true){
// is.write(""+Math.random());//触发我们的messageSent方法嘞// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
}
//处理消息的地方
class ClientHandler extends IoHandlerAdapter {
private String values;
public ClientHandler(String values) {
this.values = values;
}
public void setValues(String values){
this.values = values;
}@Overridepublic void sessionOpened(IoSession session) {
System.out.println("session write");session.write(values);
}
@Overridepublic void messageReceived(IoSession session, Object message)throws Exception {
System.out.println("message received");System.out.println(message);
}
@Overridepublic void messageSent(IoSession session, Object message) throws Exception {
System.out.println("message sent");super.messageSent(session, message);
}
}
完成一个程序的编写之后,我们会对框架有一个概要的了解了。那么下面就是真正的去研究一下架构的问题了。