mina框架中
log能打印出来收到的信息,但是就是不进入messageReceived()
解决办法:
是没有换行符 错误发送 发送字符串:123(十六进制为31 32 33)这种发送无法触发messageReceived 正确发送 在原有十六进制末尾上加0D 0A(换行符) ,变为31 32 33 0D 0A 即可触发messageReceived!
(\n)
编写一个服务端
//创建IoService的实例
IoAcceptor acceptor = new NioSocketAcceptor();
//设置过滤链 日志、编解码
acceptor.getFilterChain().addLast("logger", new LoggingFilter());
acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
//设置处理器 就是业务逻辑处理的地方
acceptor.setHandler(new TimeServerHandler());
//让其监听某个端口
acceptor.bind(new InetSocketAddress(9123));
IoAcceptor connector = new NioSocketConnector();
connector.setConnectTimeoutMillis(PushConstant.CONNECT_TIMEOUT);
// 设置日志输出工厂
connector.getFilterChain().addLast("logger", new LoggingFilter());
// 设置请求和响应对象的编解码操作
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ByteArrayCodecFactory()));
// 创建心跳工厂
ClientKeepAliveMessageFactory heartBeatFactory = new ClientKeepAliveMessageFactory();
// 当读操作空闲时发送心跳
KeepAliveFilter heartBeat = new KeepAliveFilter(heartBeatFactory, IdleStatus.READER_IDLE);
// 设置是否将事件继续往下传递
heartBeat.setForwardEvent(true);
// 设置心跳包请求后超时无反馈情况下的处理机制,默认为关闭连接,在此处设置为输出日志提醒
heartBeat.setRequestTimeoutHandler(KeepAliveRequestTimeoutHandler.LOG);
//设置心跳频率
heartBeat.setRequestInterval(180);
connector.getFilterChain().addLast("keepAlive", heartBeat);
// 设置接收和发送缓冲区大小
connector.getSessionConfig().setReceiveBufferSize(1024);
connector.getSessionConfig().setSendBufferSize(1024);
// 设置读取空闲时间:单位为s
connector.getSessionConfig().setReaderIdleTime(180);
// 设置长连接业务逻辑处理类Handler
LongConnectHandler longConnectHandler = new LongConnectHandler();
connector.setHandler(longConnectHandler);
public class TimeServerHandler extends IoHandlerAdapter{
//设置一个变量
public static int count=0;
//当捕获到异常时会触发(这里不做任何处理,仅仅打印一下)
public void execptionCaught(IoSession session,Throwable cause) throws Exception {
cause.printStackTrace();
}
//当接收到数据时触发
public void messageReceived(IoSession session, Object message) {
String mes=message.toString();
//当接受到的数据是quit时或者用户请求大于2次关闭连接
if(mes.trim().equalsIgnoreCase("quit")||count>2) {
System.out.println("正在退出时间服务器");
session.write("正在退出时间服务器。。。。");
session.close();
return;
}
//向客户端回复一个当前时间
Date date = new Date();
session.write(date.toString());
System.out.println("message writen:"+mes);
count++;
}
}
客户端
//创建IoService实例
NioSocketConnector connector = new NioSocketConnector();
//设置过滤链
connector.getFilterChain().addLast("logger", new LoggingFilter());
connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
//设置处理器
connector.setHandler(new TcpClientHandler());
//连接地址
ConnectFuture connect = connector.connect(new InetSocketAddress("localhost",9123));
IoHandlerAdapter
public class IoHandlerAdapter implements IoHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(IoHandlerAdapter.class);
public IoHandlerAdapter() {}
public void sessionCreated(IoSession session) throws Exception {}
public void sessionOpened(IoSession session) throws Exception {}
public void sessionClosed(IoSession session) throws Exception {}
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {}
public void exceptionCaught(IoSession session, Throwable cause) throws Exception {}
public void messageReceived(IoSession session, Object message) throws Exception {}
public void messageSent(IoSession session, Object message) throws Exception {}
public void inputClosed(IoSession session) throws Exception {session.closeNow();}
public void event(IoSession session, FilterEvent event) throws Exception {}
}
messageReceived
@Override
public void messageReceived(IoSession session, Object message) throws Exception {
log.debug("服务端收到信息-------------");
//获取客户端发过来的key
String key = message.toString();
System.out.println("message :"+message.toString());
String carPark_id = key.substring(key.indexOf("=") + 1);
System.out.println("carPark_id :"+carPark_id);
//保存客户端的会话session
SessionMap sessionMap = SessionMap.newInstance();
sessionMap.addSession(carPark_id, session);
}
@Override
public void messageSent(IoSession session, Object message) throws Exception {
log.debug("------------服务端发消息到客户端---");
}
@Override
public void sessionClosed(IoSession session) throws Exception {
// TODO Auto-generated method stub
log.debug("远程session关闭了一个..." + session.getRemoteAddress().toString());
}
@Override
public void sessionCreated(IoSession session) throws Exception {
log.debug(session.getRemoteAddress().toString() +"----------------------create");
}
@Override
public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
log.debug(session.getServiceAddress() +"IDS");
}
@Override
public void sessionOpened(IoSession session) throws Exception {
log.debug("连接打开:"+session.getLocalAddress());
}
消息处理类
public class MinaServerHanlder extends IoHandlerAdapter {
private int count = 0;
// 由底层决定是否创建一个session
public void sessionCreated(IoSession session) {System.out.println("新客户连接");}
// 创建了session 后会回调sessionOpened
public void sessionOpened(IoSession session) throws Exception {
count++;
System.out.println("第 " + count + " 个 client 登陆!address: : " + session.getRemoteAddress());
sessionWrite(session);
}
// 获取session连接,用来随时向客户端发送消息
public void sessionWrite(IoSession session) throws Exception {
session.write("Sent by Server1"+1);
session.write("Sent by Server1"+2);
}
// 当收到了客户端发送的消息后会回调这个函数
public void messageReceived(IoSession session, Object message) throws Exception {
System.out.println("服务器收到客户端发送指令 :" );
System.out.println(message);
// session.write("Sent by Server1");
// messageSent(session,"Sent by Server2");
}
public void messageSent(IoSession session, Object message) {
System.out.println("message send to client");
// session.write("Sent by Server3");
}
// session 关闭调用
public void sessionClosed(IoSession session) {
System.out.println("one client disconnect");
session.closeNow();
}
// session 空闲的时候调用
public void sessionIdle(IoSession session, IdleStatus status) {
System.out.println("connect idle");
}
// 异常捕捉
public void exceptionCaught(IoSession session, Throwable cause) {
System.out.println("throws exception");
}
}
客户端消息处理
public class MinaClientHanlder extends IoHandlerAdapter {
public void sessionOpened(IoSession session) throws Exception {
System.out.println("客户端登陆");
session.write("HelloWorld");
// messageReceived(session,"");
for (int i = 0; i < 10; i++) {
session.write("p 412703840,4,1,1410248991,73451566,22615771,1239,125,90,0,0,1,900\r\n"
+ "p 412703840,4,1,1410248991,73451566,22615771,1239,125,90,0,0,1,900\r\n"
+ "p 412703840,4,1,1410248991,73451566,22615771,1239,125,90,0,0,1,900\r\n"
+ "p 412703840,4,1,1410248991,73451566,22615771,1239,125,90,0,0,1,900");
}
}
public void sessionClosed(IoSession session){
System.out.println("client close");
}
public void messageReceived(IoSession session , Object message)throws Exception{
System.out.println("客户端接受到了消息"+message) ;
// session.write("Sent by Client1");
}
}
https://uias.sit.spdb.com/IDP/MobCheck.aspx
所有处理I / O事件都由Mina触发。接口所有活动中心的完成,都在过滤器链结束之后。
-
IoHandler有如下方法:
-
· sessionCreated
-
· sessionOpened
-
· sessionClosed
-
· sessionIdle
-
· exceptionCaught
-
· messageReceived
-
· messageSent
Mina IoHandler 事件触发机制
1.1.1. sessionCreated事件
当创建一个新连接时触发Session会话创建的事件。对TCP而言,它是的连接接受的结果,当接收到一个UDP数据包时对于UDP它是生成。这个函数可以用来初始化Session会话属性,并为一个特定的连接执行一次活动。
这个函数从I / O处理器线程上下文调用,因此应该实现一种消耗时间最少的方式,作为相同的线程会处理多个Session会话。
1.1.2. sessionOpened事件
当打开连接时,Session会话打开事件被调用。它总是在sessionCreated事件创建之后被调用。如果是一个已配置上网线程模型,这个函数被用于调用线程以外的I / O处理器线程。
1.1.3. sessionClosed事件
当Session关闭时,session会话的close事件被关闭。Session会话会清理活动,比如现场清理可以执行。
1.1.4. sessionIdle事件
当一个会话变得空闲时,触发会话空闲事件。这个函数不执行UDP传输。
1.1.5. exceptionCaught事件
当由用户代码或Mina抛出异常时,这个函数被调用。如果异常时一个IOException,则连接被关闭。
1.1.6. messageReceived事件
当消息被接收到时,消息接收事件触发。这就是大多数应用程序需要处理的地方。你需要关注所有你预期的消息类型。
1.1.7. messageSent事件
无论何时,当消息即响应发送时,消息发送事件被触发(调用IoSession.write())。