1、下载相应的开发包http://mina.apache.org/,MINA2.0版本包含了spring开发包,还需下载其他相关包,我的工程用到的包如下图:
2、配置spring的applicationContext.xml,配置mina服务;
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- mina server --> <bean id="serverHandler" class="com.supconit.its.server.handler.ServerHandler" /> <!-- executorFilter多线程处理 --> <bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" /> <bean id="mdcInjectionFilter" class="org.apache.mina.filter.logging.MdcInjectionFilter"> <constructor-arg value="remoteAddress" /> </bean> <bean id="codecFilter" class="org.apache.mina.filter.codec.ProtocolCodecFilter"> <constructor-arg> <!-- <bean class="org.apache.mina.filter.codec.textline.TextLineCodecFactory" />--> <!-- 处理对象流时候用ObjectSerializationCodecFactory --> <!-- <bean class="org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory" /> --> <bean class="com.supconit.its.server.handler.ServerCodeFactory" /> </constructor-arg> </bean> <bean id="loggingFilter" class="org.apache.mina.filter.logging.LoggingFilter" /> <bean id="filterChainBuilder" class="org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder"> <property name="filters"> <map> <entry key="executor" value-ref="executorFilter" /> <entry key="mdcInjectionFilter" value-ref="mdcInjectionFilter" /> <entry key="codecFilter" value-ref="codecFilter" /> <entry key="loggingFilter" value-ref="loggingFilter" /> </map> </property> </bean> <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"> <property name="customEditors"> <map> <entry key="java.net.SocketAddress"> <bean class="org.apache.mina.integration.beans.InetSocketAddressEditor" /> </entry> </map> </property> </bean> <bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor" init-method="bind" destroy-method="unbind"> <property name="defaultLocalAddress" value=":1235" /> <property name="handler" ref="serverHandler" /> <property name="filterChainBuilder" ref="filterChainBuilder" /> <property name="reuseAddress" value="true" /> </bean>
3、ServerHandler实现类
package com.supconit.its.server.handler; import java.net.InetSocketAddress; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.Set; 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; public class ServerHandler extends IoHandlerAdapter { private final int IDLE = 300; //private final Logger log = LoggerFactory .getLogger(HandlerTwo.class); private final Logger log = Logger.getLogger(ServerHandler.class.getName()); public static Set<IoSession> sessions = Collections .synchronizedSet(new HashSet<IoSession>()); /** * */ public ServerHandler(){ } @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { session.close(); //log.debug("session occured exception, so close it."); log.debug("session occured exception, so close it." + cause.getMessage()); } @Override public void sessionCreated(IoSession session) { // log.debug("remote client ["+session.getRemoteAddress().toString()+"] connected."); session.write("Welcome"); sessions.add(session); } @Override public void messageReceived(IoSession session, Object message) throws Exception { String str = message.toString(); log.debug("Message written..." + str); log.debug("客户端"+((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress()+"连接成功!"); /*if (str.trim().equalsIgnoreCase("quit")) { session.close();// return; }*/ //Date date = new Date(); //session.write(date.toString());// //session.setAttribute(remoteAddress, message); session.setAttribute("type", message); String remoteAddress = ((InetSocketAddress) session.getRemoteAddress()).getAddress().getHostAddress(); session.setAttribute("ip", remoteAddress); } @Override public void sessionClosed(IoSession session) throws Exception { log.debug("sessionClosed."); sessions.remove(session); } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { log.debug("session idle, so disconnecting......"); session.close(); log.debug("disconnected."); } // @Override public void messageSent(IoSession session, Object message) throws Exception { log.debug("messageSent."); // disconnect an idle client //session.close(); } @Override public void sessionOpened(IoSession session) throws Exception { log.debug("sessionOpened."); // session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, IDLE); } }
4、过滤器ServerCodeFactory
package com.supconit.its.server.handler; import java.nio.charset.Charset; 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 org.apache.mina.filter.codec.textline.LineDelimiter; import org.apache.mina.filter.codec.textline.TextLineDecoder; import org.apache.mina.filter.codec.textline.TextLineEncoder; public class ServerCodeFactory implements ProtocolCodecFactory { private final TextLineEncoder encoder; private final TextLineDecoder decoder; /*final static char endchar = 0x1a;*/ final static char endchar = 0x0d; public ServerCodeFactory() { this(Charset.forName("gb2312")); } public ServerCodeFactory(Charset charset) { encoder = new TextLineEncoder(charset, LineDelimiter.UNIX); decoder = new TextLineDecoder(charset, LineDelimiter.AUTO); } @Override public ProtocolDecoder getDecoder(IoSession session) throws Exception { // TODO Auto-generated method stub return decoder; } @Override public ProtocolEncoder getEncoder(IoSession session) throws Exception { // TODO Auto-generated method stub return encoder; } public int getEncoderMaxLineLength() { return encoder.getMaxLineLength(); } public void setEncoderMaxLineLength(int maxLineLength) { encoder.setMaxLineLength(maxLineLength); } public int getDecoderMaxLineLength() { return decoder.getMaxLineLength(); } public void setDecoderMaxLineLength(int maxLineLength) { decoder.setMaxLineLength(maxLineLength); } }
5、启动spring+mina socket server;
package com.supconit.its.server.test; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { /** * @param args */ public static void main(String[] args) { ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("applicationContext.xml"); } }
6、客户端测试ClintTest
package com.supconit.its.server.test; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.mina.core.future.ConnectFuture; 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; import com.supconit.its.server.handler.ServerHandler; public class ClintTest { /** * @param args */ public static void main(String[] args) { NioSocketConnector connector = new NioSocketConnector(); connector.getFilterChain().addLast( "logger", new LoggingFilter() ); //connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "GBK" )))); // connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( ))); connector.setConnectTimeout(1); connector.setHandler(new ServerHandler());// ConnectFuture cf = connector.connect( new InetSocketAddress("127.0.0.1", 1235));// cf.awaitUninterruptibly();// cf.getSession().write("hello,测试!");// //cf.getSession().write("quit");// cf.getSession().close(); cf.getSession().getCloseFuture().awaitUninterruptibly();// connector.dispose(); } }