无法从粘性服务android维护持久的XMPP连接

无法从粘性服务android维护持久的XMPP连接,android,xmpp,android-service,smack,asmack,Android,Xmpp,Android Service,Smack,Asmack,环境:为了不间断地从一对一/一对多设备传递消息,我让XMPPService作为粘性服务在后台运行。 为了接收消息,我有一个PacketListener,每当数据包到达设备时就会触发它。我使用asmack库进行客户端实现,并使用OpenFire作为我的XMPP服务器 public class XMPPService extends Service implements INetworkReceiver { private XMPPConnection mXmppConnection; privat

环境:为了不间断地从一对一/一对多设备传递消息,我让XMPPService作为粘性服务在后台运行。 为了接收消息,我有一个PacketListener,每当数据包到达设备时就会触发它。我使用asmack库进行客户端实现,并使用OpenFire作为我的XMPP服务器

public class XMPPService extends Service implements INetworkReceiver {
private XMPPConnection mXmppConnection;
private XMPPMethods xmpp;
private DatabaseHandler db;
private UserDetails user;
private SmackAndroid smack;
private Registrations registrations;
private static final String TAG="XMPPService";

@Override
public IBinder onBind(final Intent intent) {
    return new LocalBinder<XMPPService>(this);
}

@Override
public void onCreate() {
    super.onCreate();
    registrations=new Registrations(getApplicationContext());
    xmpp=XMPPMethodsImpl.getInstance(getApplicationContext());
    db=DatabaseHandler.getInstance(getApplicationContext());
    if(db!=null){
        user=db.getUserDetails();
    }
    createConnection();     
}

public void createConnection()
{
    ConnectionConfiguration connConfig = new ConnectionConfiguration(
            AppConstants.HOST, AppConstants.PORT);
    connConfig.setSASLAuthenticationEnabled(false);
    connConfig.setDebuggerEnabled(true);
    connConfig.setReconnectionAllowed(true);
    connConfig.setSecurityMode(SecurityMode.disabled);
    mXmppConnection = new XMPPConnection(connConfig);


    Thread thread=new Thread(new Runnable() {
        private Handler handler=new Handler();
        @Override
        public void run() {

            try {
                if(mXmppConnection!=null && !mXmppConnection.isConnected()){
                    mXmppConnection.connect();
                    Log.i("XMPPServiceAsync",
                            "Connected to " + mXmppConnection.getHost());
                    xmpp.setConnection(mXmppConnection);
                }
            } catch (XMPPException e) {
                e.printStackTrace();
            }

            //mXmppConnection.addConnectionListener(new XmppConnectionListener());

            handler.post(new Runnable() {

                @Override
                public void run() {
                    try {
                        if(db!=null && user!=null && mXmppConnection!=null && !mXmppConnection.isAuthenticated()){
                            if(user.getUserName()!=null && !user.getUserName().isEmpty()){
                                mXmppConnection.login(user.getUserName(), "Tp@!");
                                xmpp.setPresence(2, mXmppConnection);
                                xmpp.setConnection(mXmppConnection);
                                Log.i("XMPPServiceAsync",
                                        "Logged in as " + mXmppConnection.getUser());

                            }
                        }
                    }catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (XMPPException ex) {
                        ex.printStackTrace();
                    }


                    if(mXmppConnection.isConnected()){
                        xmpp.rejoinGroups();
                        registrations.registerMessageListener(mXmppConnection);
                        registrations.registerPacketListener(mXmppConnection);
                        registrations.registerMultiUserInvitationListener(mXmppConnection, db, user);
                        registrations.registerPingListener(mXmppConnection);
                    }

                }
            });
        }
    });

    if (thread.getState() == Thread.State.NEW )
    { 
        Log.i(TAG,"Thread State: "+ thread.getState()+"");
        thread.start(); 
    } 
}

@Override
public int onStartCommand(final Intent intent, final int flags,
        final int startId) {
    //rejoining rooms
    try{
        Log.v("XMPP Connection before rejoining",mXmppConnection+"");
        if(mXmppConnection.isConnected()){
            registrations.registerMessageListener(mXmppConnection);
            registrations.registerPacketListener(mXmppConnection);
            registrations.registerMultiUserInvitationListener(mXmppConnection, db, user);
            registrations.registerPingListener(mXmppConnection);
        }
    }catch(Exception e){
        e.printStackTrace();
    }

    return Service.START_STICKY;
}


@Override
public boolean onUnbind(final Intent intent) {
    return super.onUnbind(intent);

}


@Override
public void onDestroy() {
    super.onDestroy();

}

@Override
public void reEstablishConnection() {
    createConnection();
}
公共类XMPPService扩展服务实现INetworkReceiver{
专用XMPP连接MXMPP连接;
私有xmpp方法xmpp;
专用数据库处理程序数据库;
私有用户详细信息用户;
私密的smack和ROID smack;
私人注册;
私有静态最终字符串TAG=“XMPPService”;
@凌驾
公共IBinder onBind(最终目的){
返回新的LocalBinder(此);
}
@凌驾
public void onCreate(){
super.onCreate();
注册=新注册(getApplicationContext());
xmpp=xmppmethodsiml.getInstance(getApplicationContext());
db=DatabaseHandler.getInstance(getApplicationContext());
如果(db!=null){
user=db.getUserDetails();
}
createConnection();
}
public void createConnection()
{
ConnectionConfiguration ConnconConfig=新连接配置(
AppConstants.HOST、AppConstants.PORT);
connConfig.setaslauthenticationenabled(false);
connConfig.setDebuggerEnabled(true);
connConfig.setReconnectionAllowed(true);
connConfig.setSecurityMode(SecurityMode.disabled);
mXmppConnection=新的XMPPConnection(connconconfig);
Thread Thread=新线程(new Runnable(){
私有处理程序=新处理程序();
@凌驾
公开募捐{
试一试{
if(mXmppConnection!=null&!mXmppConnection.isConnected()){
mXmppConnection.connect();
Log.i(“XMPPServiceAsync”,
“已连接到”+mXmppConnection.getHost());
xmpp.setConnection(mXmppConnection);
}
}捕获(XMPPException e){
e、 printStackTrace();
}
//addConnectionListener(新的XmppConnectionListener());
handler.post(新的Runnable(){
@凌驾
公开募捐{
试一试{
如果(db!=null&&user!=null&&mXmppConnection!=null&&mXmppConnection.isAuthenticated()){
if(user.getUserName()!=null&&!user.getUserName().isEmpty()){
mXmppConnection.login(user.getUserName(),“Tp@!”);
xmpp.setPresence(2,MXMPP连接);
xmpp.setConnection(mXmppConnection);
Log.i(“XMPPServiceAsync”,
“以“+mXmppConnection.getUser())的身份登录”;
}
}
}捕获(非法状态){
e、 printStackTrace();
}捕获(XMPPException-ex){
例如printStackTrace();
}
if(mXmppConnection.isConnected()){
xmpp.rejoinGroups();
注册。注册信息发送器(mXmppConnection);
registrations.RegisterPackageListener(mXmppConnection);
registrations.registerMultiUserInvitationListener(MXMPPC连接,数据库,用户);
registrations.registerPingListener(mXmppConnection);
}
}
});
}
});
if(thread.getState()==thread.State.NEW)
{ 
Log.i(标记,“线程状态:“+Thread.getState()+”);
thread.start();
} 
}
@凌驾
公共int onStartCommand(最终意图、最终int标志、,
最终国际标准(TID){
//重新加入房间
试一试{
Log.v(“重新加入前的XMPP连接”,mXmppConnection+”);
if(mXmppConnection.isConnected()){
注册。注册信息发送器(mXmppConnection);
registrations.RegisterPackageListener(mXmppConnection);
registrations.registerMultiUserInvitationListener(MXMPPC连接,数据库,用户);
registrations.registerPingListener(mXmppConnection);
}
}捕获(例外e){
e、 printStackTrace();
}
return Service.START\u STICKY;
}
@凌驾
公共布尔onUnbind(最终目的){
返回super.onUnbind(intent);
}
@凌驾
公共空间{
super.ondestory();
}
@凌驾
公共无效重新建立连接(){
createConnection();
}
}

问题:当设备保持空闲一段时间时,设备与XMPP服务器断开连接,连接变为空,这违反了XMPP协议的规范,该协议规定XMPP服务器在我们强制注销之前保持与设备的持续连接。连接变为空的原因未知。当连接变为null时,PacketListener停止工作

我所做的一切:

  • 实现了用于连接到服务器和初始化侦听器的粘性服务
  • 实现AlarmManager以检查服务是否在后台运行。它还会定期检查连接是否处于活动状态并进行身份验证。(排空蓄电池)
  • 根据XMPP规范XEP-0199实施Ping管理器
  • 有人能调查一下吗。

    当设备保持空闲一段时间时,设备将断开与XMPP服务器的连接,连接变为空

    很可能,您的进程已终止

    这违反了XMPP协议的规范,该协议规定,在我们强制注销之前,XMPP服务器保持与设备的持久连接

    那么,没有任何移动设备可以遵守XMPP协议规范,如中所示