mina 心跳 时间间隔 失效
重连的时候有时候 会导致 时间间隔 失效,重新设置了
keepAliveFilter
也不行,
日志
I/KeepAliveFilter: 间隔时间是1
I/KeepAliveFilter: message sent5465-6041 msg= pingI/KeepAliveFilter: message write5465-6041
I/KeepAliveFilter: 间隔时间是1
I/KeepAliveFilter: message sent5465-6041 msg= ping
I/KeepAliveFilter: message write5465-6041
I/KeepAliveFilter: 间隔时间是1
I/KeepAliveFilter: message sent5465-6041 msg= ping
\mina_push\src\main\java\org\apache\mina\filter\keepalive\KeepAliveFilter.java
@Override
public void messageSent(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
Object message = writeRequest.getMessage();
Log.i(this.getClass().getSimpleName(),"间隔时间是" + requestInterval);
Log.i(this.getClass().getSimpleName(), "message sent"+android.os.Process.myPid()+'-'+android.os.Process.myTid() + " msg= " + message);
// if (!isKeepAliveMessage(session, message)) {
nextFilter.messageSent(session, writeRequest);
// }
}
其中的属性是private volatile int requestInterval; private volatile int requestTimeout;
估计是 volatile 导致的
有文章提到
方法1.不可行 synchronize
如何解决volatile的线程安全问题
解决线程安全问题,不要忘了开篇时候说道的原子性,多线程会有问题,我们是否可以让它实现原子性的操作??当然可以,就是我们的synchronize关键字,在多个线程对同一个变量进行访问时,做一下控制,只让一个线程来操作,这样就不会出现线程安全问题;最典型的操作:
单例模式中的双重校验!
到这里就基本结束了,不知道小编的这些见解有没有帮你解答心中的疑惑呢?
方法二 可行,判断下 equestInterval,如果<30 >100 设置为60 即可
@Override
public void messageSent(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
Object message = writeRequest.getMessage();
Log.i(this.getClass().getSimpleName(),"间隔时间是" + requestInterval);
// modied by yanggg 18 04 17
if(requestInterval < 10 || requestInterval>100){
requestInterval = 60;
requestTimeout = 30;
}
Log.i(this.getClass().getSimpleName(), "message sent"+android.os.Process.myPid()+'-'+android.os.Process.myTid() + " msg= " + message);
// if (!isKeepAliveMessage(session, message)) {
nextFilter.messageSent(session, writeRequest);
// }
}
======测试结果=======
I/KeepAliveFilter: message write2899-3343
I/KeepAliveFilter: 间隔时间是1I/KeepAliveFilter: message sent2899-3343 msg= ping
I/KeepAliveFilter: message write2899-3343
I/KeepAliveFilter: 间隔时间是60
I/KeepAliveFilter: message sent2899-3343 msg= ping
===========================================================
第二个问题 。断线重连的方式 2种
第一种重连的方式
// 断线重连回调拦截器
connector.getFilterChain().addFirst("reconnection", new IoFilterAdapter() {
@Override
public void sessionClosed(NextFilter nextFilter, IoSession ioSession) throws Exception {
for(;;){
try{
Thread.sleep(8000);
// 因为是多线程 有可能其他线程已经重新连接了
// TODO 有时候 重连后ping的时间间隔会变成很短,估计是重连了2个连接导致的错误
if (!session.isConnected()){
//有时候心跳的设置会丢失
//初始化心跳
//if (keepAliveFilter == null) {
// }
//keepAliveFilter = new KeepAliveFilter(new ClientKeepAliveMessageFactoryImp(),
// IdleStatus.READER_IDLE,
// KeepAliveRequestTimeoutHandler.DEAF_SPEAKER,
// heartBeatInterval,
// Config.KEEP_ALIVE_RESPONSE_TIMEOUT);
// Log.i(TAG, "心跳间隔重新设置为" + heartBeatInterval + "超时时间:" + Config.KEEP_ALIVE_RESPONSE_TIMEOUT);
//替换掉原来的
connector.getFilterChain()
.replace("keepalive", keepAliveFilter);
ConnectFuture future = connector.connect();
future.awaitUninterruptibly();// 等待连接创建成功
session = future.getSession();// 获取会话
if(session.isConnected()){
Log.i(TAG,"reconnection 断线重连["+ connector.getDefaultRemoteAddress().getHostName() +":"+ connector.getDefaultRemoteAddress().getPort()+"]成功");
break;
}
}
}catch(Exception ex){
Log.i(TAG, "reconnection 重连服务器登录失败,3秒再连接一次:" + ex.getMessage());
}
}
}
});
connector.addListener(new IoListener() {
@Override
public void sessionDestroyed(IoSession arg0) throws Exception {
for (;;) {
try {
Thread.sleep(9000);
//因为是多线程 有可能其他线程已经重新连接了
if (!session.isConnected()){
ConnectFuture future = connector.connect();
future.awaitUninterruptibly();// 等待连接创建成功
session = future.getSession();// 获取会话
if (session.isConnected()) {
Log.i(TAG,"addListener IoListener 断线重连[" + connector.getDefaultRemoteAddress().getHostName() + ":" + connector.getDefaultRemoteAddress().getPort() + "]成功");
break;
}
}
} catch (Exception ex) {
Log.i(TAG,"addListener IoListener 重连服务器登录失败,3秒再连接一次:" + ex.getMessage());
}
}
}
});
package com.andy.mina_push.nat;
/**
* Created by win on 2018/4/15.
*/
import org.apache.mina.core.service.IoService;
import org.apache.mina.core.service.IoServiceListener;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
public class IoListener implements IoServiceListener{
@Override
public void serviceActivated(IoService arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void serviceDeactivated(IoService arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void serviceIdle(IoService arg0, IdleStatus arg1) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionCreated(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void sessionClosed(IoSession session) throws Exception {
}
@Override
public void sessionDestroyed(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
}
}