场景要求在web项目中使用mina与一些客户端通讯。
一、maven引包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chhuang</groupId>
<artifactId>ch-huaao</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>ch-huaao Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--spring 工具包 日志 等的引包工作都在这个自己写的核心包里了-->
<dependency>
<groupId>com.chhuang</groupId>
<artifactId>ch-mybatis-core</artifactId>
<version>0.0.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- mina -->
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-integration-beans</artifactId>
<version>2.0.7</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-core</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.mina</groupId>
<artifactId>mina-integration-spring</artifactId>
<version>1.1.7</version>
</dependency>
<!-- /mina -->
</dependencies>
<build>
<finalName>ch-huaao</finalName>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
其中这个插件很重要不然会报错
org.apache.felix
maven-bundle-plugin
true
二、服务器端spring整合mina的配置
mini.properties
mina.initPoolSize=10
mina.maximumPoolSize=500
mina.serverPort=8808
mina.bothIdleTime=86400
mina.receiveBufferSize=4096
mina.sendBufferSize=4096
spring-mina.xml
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<!-- 引入定义JDBC连接的属性文件 -->
<context:property-placeholder location="classpath:config/mina.properties" />
<!-- 配置多线程过滤器 -->
<bean id="executorFilter" class="org.apache.mina.filter.executor.ExecutorFilter" >
<constructor-arg index="0" value="${mina.initPoolSize}" />
<constructor-arg index="1" value="${mina.maximumPoolSize}" />
</bean>
<!-- 配置mdc操作过滤器 -->
<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" >
<constructor-arg index="0" type="java.nio.charset.Charset" value="UTF-8" />
</bean>
</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 id="serverHandler" class="com.chhuang.huaao.handler.ServerHandler" ></bean>
<!-- 配置地址 -->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.net.SocketAddress" value="org.apache.mina.integration.beans.InetSocketAddressEditor" />
</map>
</property>
</bean>
<!-- 基于构造方法的注入方式 -->
<bean id="ioAcceptor" class="org.apache.mina.transport.socket.nio.NioSocketAcceptor"
init-method="bind" destroy-method="unbind">
<property name="defaultLocalAddress" value=":${mina.serverPort}" />
<property name="handler" ref="serverHandler" />
<property name="filterChainBuilder" ref="filterChainBuilder" />
<property name="reuseAddress" value="true" />
</bean>
<!-- session config -->
<bean id="sessionConfig" factory-bean="ioAcceptor" factory-method="getSessionConfig" >
<property name="bothIdleTime" value="${mina.bothIdleTime}"/>
<property name="receiveBufferSize" value="${mina.receiveBufferSize}"/>
<property name="sendBufferSize" value="${mina.sendBufferSize}"/>
</bean>
</beans>
三、服务器业务处理ServerHandler自己的handler
package com.chhuang.huaao.handler;
import java.util.Date;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import com.chhuang.utils.date.DateUtil;
public class ServerHandler extends IoHandlerAdapter {
private static final Log log = LogFactory.getLog(ServerHandler.class);
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
String content = message.toString();
log.debug("服务端接收到的数据为: " + content);
content = content.trim();
if(content.equalsIgnoreCase("login")) {
}else if(content.equalsIgnoreCase("logout")) {
session.close(true);
return;
}
//回复服务器接收到的时间
session.write(DateUtil.date2String(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
super.messageReceived(session, message);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
log.debug("服务端发送信息成功: " + message.toString());
super.messageSent(session, message);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
log.debug("服务端发送异常: " + cause.getMessage());
super.exceptionCaught(session, cause);
}
@Override
public void sessionCreated(IoSession session) throws Exception {
log.debug("服务端与客户端创建连接...");
super.sessionCreated(session);
}
@Override
public void sessionOpened(IoSession session) throws Exception {
log.debug("服务端与客户端连接打开...");
super.sessionOpened(session);
}
@Override
public void sessionClosed(IoSession session) throws Exception {
log.debug("服务端与客户端连接关闭...");
super.sessionClosed(session);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
log.debug("服务端进入空闲状态: " + session.getIdleCount(status));
super.sessionIdle(session, status);
}
}
四、mina客户端ClientHandler
package com.chhuang.huaao.handler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
public class ClientHandler extends IoHandlerAdapter {
private static final Log log = LogFactory.getLog(ClientHandler.class);
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
log.debug("客户端收到消息: " + message.toString());
super.messageReceived(session, message);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
log.debug("客户端消息发送成功: " + message.toString());
super.messageSent(session, message);
}
@Override
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
log.debug("客户端异常: " + cause.getMessage());
super.exceptionCaught(session, cause);
}
@Override
public void sessionCreated(IoSession session) throws Exception {
log.debug("客户端会话创建...");
super.sessionCreated(session);
}
@Override
public void sessionOpened(IoSession session) throws Exception {
log.debug("客户端会话打开...");
super.sessionOpened(session);
}
@Override
public void sessionClosed(IoSession session) throws Exception {
log.debug("客户端会话关闭...");
super.sessionClosed(session);
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
log.debug("客户端会话休眠: " + session.getIdleCount(status));
super.sessionIdle(session, status);
}
}
五、客户端简单启动程序
package com.chhuang.huaao;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
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.chhuang.huaao.handler.ClientHandler;
/**
* Hello world!
*
*/
public class App {
private static final Log log = LogFactory.getLog(App.class);
private static final String IP = "192.168.200.102";
private static final int PORT = 8808;
public static void main(String[] args) {
log.debug("打开客户端...");
IoConnector connector = new NioSocketConnector();
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); //设置编码过滤器
connector.setHandler(new ClientHandler());//设置事件处理器
ConnectFuture connectFuture = connector.connect(new InetSocketAddress(IP, PORT));//建立连接
connectFuture.awaitUninterruptibly();//等待连接创建完成
connectFuture.getSession().write("哈哈");//发送消息
// connectFuture.getSession().close(true);
// connectFuture.getSession().getCloseFuture().awaitUninterruptibly();//等待连接断开
// connector.dispose();
}
}
可以客户端和服务器分开两个项目写,一个写成web服务发布到tomcat里,一个写成java程序打包成jar直接运行,测试通过。