4

I am working on chat application and using ejabberd saas edition as xmpp server for it. I am using smack library ver-4.2.3. To keep connection alive I am using ping manager. Here is the code I am using:

ReconnectionManager.getInstanceFor(AppController.mXmpptcpConnection).enableAutomaticReconnection();
ServerPingWithAlarmManager.onCreate(context);
ServerPingWithAlarmManager.getInstanceFor(AppController.mXmpptcpConnection).setEnabled(true);
ReconnectionManager.setEnabledPerDefault(true);

//int i = 1;
// PingManager.setDefaultPingInterval(i);
PingManager.getInstanceFor(AppController.mXmpptcpConnection).setPingInterval(300);

I am using sticky-service also for connection, but when I keep my application open (ideal-state) for 15-20 mins then the connection is lost, so I am using ping manger to resolve this issue.

Is there any other better way of doing it or ping manager is the only option?

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
Snehangshu Kar
  • 445
  • 2
  • 13
  • I would recommend you to study [Conversation project](https://github.com/siacs/Conversations) which is using stream management too. See [XmppConnection](https://github.com/siacs/Conversations/blob/2fc4ca719de5466e1727c47c55f397393bfb26e1/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java) – Chathura Wijesinghe Aug 13 '18 at 02:16

4 Answers4

3

Insted of pinging chat server constantly, you better to use ConnectionListener() in smack library. You need to use something like this:

XMPPTCPConnection connection;
// initialize your connection

// handle the connection
connection.addConnectionListener(new ConnectionListener() {
      @Override 
      public void connected(XMPPConnection connection) {

      }

      @Override 
      public void authenticated(XMPPConnection connection, boolean resumed) {

      }

      @Override 
      public void connectionClosed() {
        // when the connection is closed, try to reconnect to the server.
      }

      @Override 
      public void connectionClosedOnError(Exception e) {
        // when the connection is closed, try to reconnect to the server.
      }

      @Override 
      public void reconnectionSuccessful() {

      }

      @Override 
      public void reconnectingIn(int seconds) {

      }

      @Override 
      public void reconnectionFailed(Exception e) {
        // do something here, did you want to reconnect or send the error message?
      }
    });
ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
2

Yes, There is. Few points before the solution

  1. Make your service STICKY, with a foreground notification as it would be necessary to work on or after Build.VERSION_CODES.O
  2. This sticky service, you should start on every boot, via BOOT_COMPLETED intent action and starting this foreground service from receiver.
  3. Yes, Now it is always there, Now you can always go for checking your connection
  4. You can use google-volley for making connections and even you can communicate using it.
  5. There is no good documentation on it, But i like it much, as it works flawlessly once added the dependency successfully.
  6. Adding this dependency will take time as i said no good documentation..

For communication :

StringRequest stringRequest = new StringRequest(Request.Method.POST, "https://oniony-leg.000webhostapp.com/user_validation.php",
            new Response.Listener<String>()
            {
                @Override
                public void onResponse(String response)
                {
                    serverKeyResponse = response;
                    // get full table entries from below toast and writedb LICENSETABLE
                    //Toast.makeText(getActivity(),response,Toast.LENGTH_LONG).show();
                    showKeyResponse();
                   // Log.d("XXXXXX XXXXX", "\n SUCCESS : "+serverKeyResponse);

                }
            },
            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error)
                {
                    serverKeyResponse = error.toString();
                    // show below toast in alert dialog and it happens on slow internet try again after few minutes
                    // on ok exit app
                    // Toast.makeText(getActivity(),error.toString(),Toast.LENGTH_LONG).show();
                    showKeyResponse();
                    //Log.d("YYYYYY YYYYYY", "\n FAILURE : "+serverKeyResponse);
                }
            })
    {
        @Override
        protected Map<String,String> getParams()
        {
            Map<String,String> params = new HashMap<String, String>();
            params.put("INPUT",LicenseKey.getText().toString());
            params.put("USER", MainActivity.deviceid);
            return params;
        }

    };

    RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
    requestQueue.add(stringRequest);

You just have to reply ECHO "SUCCESS" from server using a php ( or whatever server side language you like ). In response check for SUCCESS presence, any any other cases.., Use other KEYWORDS YOU LIKE. You can handle Server response errors too. Even you can communicate from android in request - response handshake. But you have to implement few handshake on your own.

I Hope, It helps...

sandhya sasane
  • 1,334
  • 12
  • 19
  • Thanks for the quick reply! How can this replace the ping manager? We have to keep connection alive with Ejabberd XMPP server, not with our server. And in smack we have PingManager for it. – Snehangshu Kar Apr 20 '18 at 07:04
2

Best way to keep the alive connection with XMPP server you should reconnect after every network change.

Like this:

public class NetworkStateChangeReceiver extends BroadcastReceiver {

private Context context;
private static NetworkStateChangeListener mListener;

@Override
public void onReceive(Context context, Intent intent) {

this.context = context;
try {
if (!ApplicationHelper.isInternetOn(context)) {
if (mListener != null) {
mListener.OnInternetStateOff();
}
return;
} else {
XMPPTCPConnection xmpptcpConnection = XmppConnectionHelper.getConnection();
if(!StringHelper.isNullOrEmpty(new SessionManager(context).getAuthenticationToken())) {
Intent XmppConnectionServicesIntent = new Intent(context, XmppConnectionServices.class);
context.stopService(XmppConnectionServicesIntent);
context.startService(XmppConnectionServicesIntent);
}
}

} catch (Exception e) {
e.printStackTrace();
}
}

//to initialize NetworkStateChangeListener because null pointer exception occurred
public static void setNetworkStateChangeListener(NetworkStateChangeListener listener) {
mListener = listener;
}

}
Sagar Maiyad
  • 12,655
  • 9
  • 63
  • 99
Shavareppa
  • 990
  • 1
  • 6
  • 14
  • 1
    The above Code is used for reconnecting with server,To keepAlive use Android alarm manager or Smack Ping manager so that u can send Presence to Server – Shavareppa Aug 17 '18 at 10:19
  • 1
    Thanks Shavareppa, I used Alarm Manager instead of Ping Manager and It is Working. but I losses the messages while Connecting to the Server – Snehangshu Kar Aug 17 '18 at 10:31
1

Use the ReconnectionManager class as described here.

ReconnectionManager manager = ReconnectionManager.getInstanceFor(connection);
manager.enableAutomaticReconnection();

It will automatically re-connect when necessary.

driver733
  • 401
  • 2
  • 6
  • 21