2014-04-15 2 views
1

비트가 이상하지만 XMPP 연결의 연결 상태를 모니터링하는 데 문제가 있습니다. Smack (3.4.1) 및 Openfire (3.8.2)를 사용하고 있습니다.Smack XMPP 연결 상태, 잘못된 데이터

Openfire는 클라이언트의 연결이 끊겼음을보고합니다. 중간 서버 요청을 담당하는 원격 클라이언트 BOT도 마찬가지입니다. 그러나 장치 자체는 여전히 연결되어 있다고 믿습니다. 그래서 무언가가 갑자기 연결을 죽였습니다.

Openfire 관리 콘솔을 통해 수동으로 클라이언트 연결을 닫으면 시나리오를 복제 할 수 있습니다. 이 작업을 수행 한 후, 클라이언트는 여전히 다음과 같은 세부 사항, 연결 부분을보고 : 코드에서

04-15 09:48:23.349: D/BXC(18166): Checking Xmpp connection status 
04-15 09:48:23.349: I/BXC(18166): Xmpp Connection still valid 
04-15 09:48:23.349: D/BXC(18166): isNull=false 
04-15 09:48:23.349: D/BXC(18166): isConnected()=true 
04-15 09:48:23.349: D/BXC(18166): isAuthenticated()=true 
04-15 09:48:23.349: D/BXC(18166): xmppConnectorRunning=true 
04-15 09:48:23.349: D/BXC(18166): socketIsClosed()=false 
04-15 09:48:23.349: D/BXC(18166): Are we logged in? 
04-15 09:48:23.349: I/BXC(18166): Yes - Logged in. 

:

Log.d("BXC", "isNull=" + (xConnection == null)); 
Log.d("BXC", "isConnected()=" + xConnection.isConnected()); 
Log.d("BXC", "isAuthenticated()=" + xConnection.isAuthenticated()); 
Log.d("BXC", "xmppConnectorRunning=" + Globals.backgroundXmppConnectorRunning); 
Log.d("BXC", "socketIsClosed()=" + xConnection.isSocketClosed()); 

의 문제점은, 내가 다시 시작할 때까지 연결이이 상태로 유지됩니다 앱. XMPP 연결 상태를 확인하는 데 사용할 수있는 최상의 값/데이터/변수/메서드 호출은 무엇입니까?

여기 내 BackgroundXmppConnector 서비스 코드 (나는 아마도 길을 따라 뭔가를 borked했지만, 나는 그것을 볼 수 없습니다)입니다 :

내부 변수/회원 등이 주변에 실제 방법이 없었다
package com.goosesys.gaggle.services; 

import java.util.Collection; 

import org.jivesoftware.smack.Chat; 
import org.jivesoftware.smack.ChatManagerListener; 
import org.jivesoftware.smack.ConnectionConfiguration; 
import org.jivesoftware.smack.ConnectionListener; 
import org.jivesoftware.smack.Roster; 
import org.jivesoftware.smack.Roster.SubscriptionMode; 
import org.jivesoftware.smack.RosterListener; 
import org.jivesoftware.smack.XMPPConnection; 
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode; 
import org.jivesoftware.smack.XMPPException; 
import org.jivesoftware.smack.packet.Message; 
import org.jivesoftware.smack.packet.Presence; 

import com.google.gson.Gson; 
import com.goosesys.gaggle.Globals; 
import com.goosesys.gaggle.application.AppSettings; 
import com.goosesys.gaggle.application.Utility; 

import android.app.Service; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.os.Binder; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.IBinder; 
import android.util.Log; 

public class BackgroundXmppConnector extends Service 
{ 
    private ConnectionConfiguration acc; 
    private XMPPConnection xConnection; 
    private final IBinder mBinder = new XmppBinder(); 
    private final Handler mHandler = new Handler(); 
    private static int mInterval = (1 * 60 * 1000); 
    private static boolean bConnecting = false; 
    private static final Object connectLock = new Object(); 

    private final Runnable checkConnection = new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      checkConnectionStatus();  
     } 
    }; 

    @Override 
    public void onCreate() 
    { 
     Log.i("BXC", "BackgroundXmppConnector Service has been created"); 

     // Checks the connection state every 1 minute // 
     mHandler.postDelayed(checkConnection, mInterval); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
//  SmackAndroid.init(getApplicationContext()); 

     Log.d("BXC", "Xmpp Connector Started"); 
     if(xConnection == null) 
     { 
      checkConnectionStatus(); 
     } 

     return Service.START_STICKY; 
    } 

    private void setupConnection() 
    {  
     try 
     { 
      acc = new ConnectionConfiguration(AppSettings.XMPP_SERVER_HOST, 
        AppSettings.XMPP_SERVER_PORT); 
      acc.setSecurityMode(SecurityMode.disabled); 
      acc.setSASLAuthenticationEnabled(false); 
      acc.setReconnectionAllowed(true); 

      xConnection = new XMPPConnection(acc); 

      xConnection.addConnectionListener(new ConnectionListener() 
      { 
       @Override 
       public void connectionClosed() 
       { 
        Log.e("BXC", "Xmpp connection closed"); 
        Globals.backgroundXmppConnectorRunning = false; 
        bConnecting = false; 
       } 

       @Override 
       public void connectionClosedOnError(Exception e) 
       { 
        Log.e("BXC", "Xmpp connection closed with error: " + e); 
        Globals.backgroundXmppConnectorRunning = false; 
        bConnecting = false; 
       } 

       @Override 
       public void reconnectingIn(int seconds) 
       { 
        Log.i("BXC", "Xmpp connection, reconnecting in " + seconds + " seconds"); 
        bConnecting = true; 
       } 

       @Override 
       public void reconnectionFailed(Exception e) 
       { 
        Log.e("BXC", "Xmpp reconnection failed: " + e); 
        Globals.backgroundXmppConnectorRunning = false; 
        bConnecting = false; 
       } 

       @Override 
       public void reconnectionSuccessful() 
       { 
        Log.i("BXC", "Xmpp reconnected successfully"); 
        Globals.backgroundXmppConnectorRunning = true; 
        bConnecting = false; 
       }   
      });      

     } 
     catch (Exception e) 
     { 
      Log.e("BXC", e.getMessage()); 
     } 
     finally 
     { 
      // Schedule another check in 1 minute // 
      mHandler.postDelayed(checkConnection, mInterval);    
     } 

     if(xConnection.isAuthenticated() == false) 
      new LoginTask().execute(); 
    } 

    public boolean sendMessage(Intent intent) 
    { 
     if(xConnection != null && xConnection.isConnected()) 
     { 
      String jsonObject; 
      Bundle extras = intent.getExtras(); 
      if(extras != null) 
      { 
       jsonObject = extras.getString("MESSAGEDATA"); 
       Message m = new Gson().fromJson(jsonObject, Message.class); 
       if(m != null) 
       { 
        sendMessage(m); 
       } 
       else 
       { 
        Log.e("BXC", "Message to send was/is null. Can't send."); 
       } 

       m = null; 
       jsonObject = null; 
       extras = null; 
      } 

      Log.i("BXC", "Sending Xmpp Packet"); 
      return true; 
     } 

     return false; 
    } 

    /* 
    * Sends message to xmpp server - message packet in form of 
    * 
    * --------------------MESSAGE PACKET------------------------- 
    * TO 
    * ----------------------- 
    * FROM 
    * ----------------------- 
    * BODY 
    *  TRANSACTION------------------------------------------- 
    *   MessageType 
    *   -------------------------------------------------- 
    *   TransactionObject 
    */ 
    private void sendMessage(Message m) 
    { 
     try 
     { 
      Log.d("BXC", "Sending transaction message to Xmpp Server"); 
      xConnection.sendPacket(m);   
     } 
     catch(Exception ex) 
     { 
      ex.printStackTrace(); 
     } 
    } 

    public boolean isConnected() 
    { 
     return xConnection.isConnected(); 
    } 

    private void checkConnectionStatus() 
    { 

     Log.d("BXC", "Checking Xmpp connection status"); 

     if(!bConnecting) 
     { 

      // if connection object is null - re-create 
      if(xConnection == null) // || xConnection.isConnected() == false 
      { 
       // The connection has stalled for some reason - attempt a reconnect 
       Log.e("BXC", "No connection. Attempting to connect."); 
       setupConnection();   
      } 
      else 
      { 
       Log.i("BXC", "Xmpp Connection still valid"); 
      } 

      Log.d("BXC", "isNull=" + (xConnection == null)); 
      Log.d("BXC", "isConnected()=" + xConnection.isConnected()); 
      Log.d("BXC", "isAuthenticated()=" + xConnection.isAuthenticated()); 
      Log.d("BXC", "xmppConnectorRunning=" + Globals.backgroundXmppConnectorRunning); 
      Log.d("BXC", "socketIsClosed()=" + xConnection.isSocketClosed()); 

      if(xConnection != null && xConnection.isConnected() == true) 
      { 
       Log.d("BXC", "Are we logged in?"); 

       if(xConnection.isAuthenticated() == false) 
       { 
        Log.e("BXC", "Nope. Logging in..."); 
        new LoginTask().execute();   
       } 
       else 
       { 
        Log.i("BXC", "Yes - Logged in."); 
       }    
      } 
      else if(xConnection == null || xConnection.isConnected() == false || xConnection.isAuthenticated() == false) 
      { 
       Log.e("BXC", "Disconnected. Attempting reconnect"); 
       new LoginTask().execute(); 
      } 
      else 
      { 
       Log.e("BXC", "Couldn't log in because connection failed."); 
      } 


     } 
     else 
     { 
      Log.e("BXC", "Already checking."); 
     } 


     // Schedule again for 5 minutes. 
     mHandler.postDelayed(checkConnection, mInterval); 
    } 

    // BINDER //////////////////////////////////////////////////////////////////////////////// 
    @Override 
    public IBinder onBind(Intent intent) 
    { 
     return mBinder; 
    } 


    // INTERNAL CLASSES ////////////////////////////////////////////////////////////////////// 
    public class XmppBinder extends Binder 
    { 
     public BackgroundXmppConnector getService(){ 
      return BackgroundXmppConnector.this; 
     } 
    } 

    private class LoginTask extends AsyncTask<Void, Void, Void> 
    { 
     @Override 
     protected Void doInBackground(Void... params) 
     { 
      try 
      { 
       bConnecting = true; 
       synchronized(connectLock) 
       { 
        if(xConnection != null && (xConnection.isSocketClosed() || !xConnection.isConnected())) 
        {     
         xConnection.connect(); 
         Log.i("BXC", "Login Credentials: " + Utility.getAndroidID(getApplicationContext()) + "/" + AppSettings.XMPP_KEYSTORE_PASSWORD); 
         xConnection.login(Utility.getAndroidID(getApplicationContext()), AppSettings.XMPP_KEYSTORE_PASSWORD);     

         xConnection.getChatManager().addChatListener(new ChatManagerListener(){ 
          @Override 
          public void chatCreated(final Chat chat, boolean createdLocally) 
          { 
           if(!createdLocally) 
           { 
            // add chat listener // 
            chat.addMessageListener(new BackgroundMessageListener(getApplicationContext())); 
           } 
          } 

         });     

         Presence p = new Presence(Presence.Type.subscribe); 
         p.setStatus("Out and About"); 
         xConnection.sendPacket(p); 

         Roster r = xConnection.getRoster();     
         r.setSubscriptionMode(SubscriptionMode.accept_all); 
         r.createEntry(AppSettings.BOT_NAME, "AbleBot", null); 
         r.addRosterListener(new RosterListener(){ 

          @Override 
          public void entriesAdded(Collection<String> addresses) 
          {    
           for(String s : addresses) 
           { 
            Log.d("BXC", "Entries Added: " + s); 
           } 
          } 

          @Override 
          public void entriesDeleted(Collection<String> addresses) 
          { 
           for(String s : addresses) 
           { 
            Log.d("BXC", "Entries Deleted: " + s); 
           }       
          } 

          @Override 
          public void entriesUpdated(Collection<String> addresses) 
          { 
           for(String s : addresses) 
           { 
            Log.d("BXC", "Entries updated: " + s); 
           }       
          } 

          @Override 
          public void presenceChanged(Presence presence) 
          { 
           Log.d("BXC", "PresenceChanged: " + presence.getFrom()); 
          }      
         }); 
        } 
       }   
      } 
      catch(IllegalStateException ex) 
      { 
       Log.e("BXC", "IllegalStateException -->"); 
       Globals.backgroundXmppConnectorRunning = false; 
       ex.printStackTrace(); 
      } 
      catch(XMPPException ex) 
      { 
       Log.e("BXC", "XMPPException -->"); 
       Globals.backgroundXmppConnectorRunning = false; 
       ex.printStackTrace(); 
      } 
      catch(NullPointerException ex) 
      { 
       Log.e("BXC", "NullPointerException -->"); 
       Globals.backgroundXmppConnectorRunning = false; 
       ex.printStackTrace(); 
      } 
      catch(Exception ex) 
      { 
       Log.e("BXC", "Exception -->"); 
       Globals.backgroundXmppConnectorRunning = false; 
       ex.printStackTrace(); 
      } 

      return null;      
      //}   
     } 

     @Override 
     protected void onPostExecute(Void ignored) 
     { 
      if(xConnection != null) 
      { 
       if(xConnection.isConnected() && (!xConnection.isSocketClosed())) 
       { 
        Log.i("BXC", "Logged in to XMPP Server"); 
        Globals.backgroundXmppConnectorRunning = true; 
        bConnecting = false; 
       } 
       else 
       { 
        Log.e("BXC", "Unable to log into XMPP Server.");  
        Globals.backgroundXmppConnectorRunning = false; 
        bConnecting = false; 
       } 
      } 
      else 
      { 
       Log.e("BXC", "Xmpp Connection object is null"); 
       Globals.backgroundXmppConnectorRunning = false; 
       bConnecting = false; 
      } 
     } 
    } 

} 

답변

1

XMPPConnector 클래스 내에서 연결 상태에 관계없이 항상 true입니다 (초기 시작 제외).

connectionClosed, connectionClosedOnError 등 : 나는이 문제를 가지고 어떻게

내가 연결 상태가 같은 콜백 메소드에 의해 정의 된 내용에 따라, 참/거짓으로 설정 전역 정적 변수를 만드는 것이 었습니다

관련 문제