Environment: For uninterrupted delivery of messages from one-to-one/one-to-many devices, I have XMPPService running in the background as STICKY service. To receive messages, I have PacketListener which fires whenever a packet arrives at the device. I am using asmack library for client side implementation and OpenFire as my XMPP server.
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();
}
}
Problem: When device remains idle for some time, device disconnects from the XMPP server and connection goes null which is against the specifications of XMPP protocol which states that XMPP server maintains persistent connection with devices until we logout forcefully. Reason behind connection going null is not known. When connection goes null, PacketListener stops working.
What all I have tried:
- Implemented sticky service for connecting to server and initializing listeners.
- Implemented AlarmManager to check if the service is running in the background. It also checks if the connection is alive and authenticated periodically. (Drains Battery)
- Implemented Ping manager according to XMPP specification XEP-0199.
Can someone please look into this.