无法保持粘滞服务android的永久XMPP连接

环境 :为了不间断地从一对一/一对多设备传递消息,我将XMPPService作为STICKY服务在后台运行。 为了接收消息,我有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();
}

}

问题:当设备空闲一段时间后,设备将断开与XMPP服务器的连接,并且连接将变为空,这违反了XMPP协议的规定,该规范声明XMPP服务器与设备保持持久连接,直到我们强制注销为止。 未知连接后的原因是否为空。 连接变为空时,PacketListener停止工作。

我所尝试的都是:

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


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

    最有可能的是,你的过程被终止。 这很正常。

    这违反了XMPP协议的规定,XMPP协议声明XMPP服务器与设备保持持久连接,直到我们强制注销为止。

    那么没有任何移动设备可以遵守XMPP协议规范,因为互联网接入不能保证和通用。 而且,用户可以在用户需要时摆脱进程。

    实现了连接服务器和初始化侦听器的粘性服务。

    这会导致您的流程和服务在Android终止流程后的某个时间重新启动。 在您的进程被终止和您的进程重新启动之间的时间窗口期间,您将不会与XMPP服务器进行通信。


    什么commonsware说。 START_STICKY只是表示Android在需要资源时可以自由地终止您的服务。 它会在一段时间后重新启动您的服务。 但是你有责任在发生XMPP连接时重新建立连接。

    链接地址: http://www.djcxy.com/p/94085.html

    上一篇: Cannot maintain persistent XMPP connection from sticky service android

    下一篇: Smack api and Openfire server presence error