androidpn源码(http://www.iteye.com/topic/1117043 ),是在这里下载的,这里灰常感谢大虾修复了系列的BUG。现在有一个客户端断网或开飞行模式或重启的时候,服务器那边不知道该用户已经下线了,而服务器端显示的还是online状态,根据在网上查到的解决方法是在服务器里的XmppIoHandler.java中的sessionCreated()方法中添加session.getConfig().setIdleTime(IdleStatus.BOTH_IDLE,180);这个时候手机USB连着电脑测试是OK的,飞行或断网等操作服务器端都可以看到客户端下线,然后又重新连上来;但如果手机拔开电脑用WIFI连接时,和上面步骤一样但是在180秒后不做任何操作客户端掉线了,然后有的时候可以重连上来,有的时候不行。查看ASMACK源码里边确实用间隔30秒的心跳包,而服务器的CONSOLE中也能看到心跳包的传送,现在为什么有心跳包传过来这个ioSession还是被闲置了呢,求大大们帮帮忙已经困扰两天了

解决方案 »

  1.   

    是这样的,第一次连接生成session1,断线立即重连生成session2,这时session1的超时还没到,等到了的时候就回调ClientSessionListener的onConnectionClose,由于他们保存的username是相同的,所以根据username来操作的话就误把已经重连上的session2移除了。在服务器端的SessionManager的ClientSessionListener里面,removeSession之前,判断一下
    HttpClient client = null;
    try {
    ClientSession session = (ClientSession) handback; Session s = getSession(session.getUsername()); if (s != session) {
    System.out.println("》》》》》》》》》不同了,忽略"
    + session.getUsername());
    return;
    } else {
    System.out
    .println("》》》》》》》》》相同,继续" + session.getUsername());
    }
      

  2.   

    是这样的,第一次连接生成session1,断线立即重连生成session2,这时session1的超时还没到,等到了的时候就回调ClientSessionListener的onConnectionClose,由于他们保存的username是相同的,所以根据username来操作的话就误把已经重连上的session2移除了。在服务器端的SessionManager的ClientSessionListener里面,removeSession之前,判断一下
    HttpClient client = null;
    try {
    ClientSession session = (ClientSession) handback; Session s = getSession(session.getUsername()); if (s != session) {
    System.out.println("》》》》》》》》》不同了,忽略"
    + session.getUsername());
    return;
    } else {
    System.out
    .println("》》》》》》》》》相同,继续" + session.getUsername());
    }
      

  3.   


    但如果是判断相同的情况下就不予以进行remove操作的话客户端断网时进行的重连username也是一样的,这时候服务器再拿这个session去取任何的username,ip等都会报错的
      

  4.   

    说了一大推,把你的核心问题表述清楚。再测试一下我这个客户端(http://files.cnblogs.com/dzchen/PushClient_v0.6.2.apk)有没有这个问题,如果有同样的问题的话,我也不知道了。
      

  5.   

    其实就是这里的问题,如果我没有表达清楚请移步看http://www.iteye.com/topic/1117043?page=13
      

  6.   

    但如果是判断相同的情况下就不予以进行remove操作的话客户端断网时进行、、、、之所以不remove是因为把session2放入sessions的时候已经把他移除了。
      

  7.   

    我的意思就是sessions里面只会出现一个username,如果第一个断线超时没到,第二个已经进来,那么第一个就被覆盖了,就应该忽略第一个的超时。
      

  8.   

    客户端应该是通过catch exception然后做restart