1、下载相应的开发包http://mina.apache.org/,MINA2.0版本包含了spring开发包,还需下载其他相关包,我的工程用到的包如下图:
2、配置spring的spring-mina-1.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- mina server -->
<bean id="serverHandler" class="minaT5.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="minaT5.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="127.0.0.1:1235" />
<property name="handler" ref="serverHandler" />
<property name="filterChainBuilder" ref="filterChainBuilder" />
<property name="reuseAddress" value="true" />
</bean>
</beans>
3、ServerHandler实现类
package minaT5;
import java.net.InetSocketAddress;
import java.util.Collections;
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 = Logger.getLogger(ServerHandler.class);
private static Set<IoSession> sessions = Collections.synchronizedSet(new HashSet<IoSession>());
/**
*
*/
public ServerHandler() {
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) {
session.close();
// log.debug("session occured exception, so close it.");
log.info("session occured exception, so close it."
+ cause.getMessage());
}
@Override
public void sessionCreated(IoSession session) {
log.info("remote client [" + session.getRemoteAddress().toString()
+ "] connected.");
session.write("welcome");
sessions.add(session);
}
@Override
public void messageReceived(IoSession session, Object message) {
String str = message.toString();
log.info("Message written " + str);
log.info("客户端"
+ ((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) {
log.info("sessionClosed.");
sessions.remove(session);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) {
log.info("session idle, so disconnecting......");
session.close();
log.info("disconnected.");
}
@Override
public void messageSent(IoSession session, Object message){
log.info("messageSent.");
// disconnect an idle client
//session.close();
}
@Override
public void sessionOpened(IoSession session){
log.info("sessionOpened.");
//
session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE, IDLE);
}
}
4、过滤器ServerCodeFactory
package minaT5;
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("UTF-8"));
}
public ServerCodeFactory(Charset charset) {
encoder = new TextLineEncoder(charset, LineDelimiter.UNIX);
decoder = new TextLineDecoder(charset, LineDelimiter.AUTO);
}
@Override
public ProtocolDecoder getDecoder(IoSession arg0) throws Exception {
return decoder;
}
@Override
public ProtocolEncoder getEncoder(IoSession arg0) throws Exception {
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 minaT5;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-mina-1.xml");
}
}
6、客户端测试ClintTest
package minaT5;
import java.net.InetSocketAddress;
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;
public class ClintTest {
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("localhost", 1235));
cf.awaitUninterruptibly();
cf.getSession().write("hello,测试!");
//cf.getSession().write("quit");//
// cf.getSession().close();
cf.getSession().getCloseFuture().awaitUninterruptibly();//
// connector.dispose();
}
}