Лучший способ сохранить живое соединение с сервером Xmpp в Android

Я работаю над приложением чата и использую ejabberd Saas Edition в качестве сервера XMPP для него. Я использую библиотеку smack ver-4.2.3. Для поддержания связи я использую ping manager. Вот код, который я использую:

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);

Я использую sticky-сервис также для соединения, но когда я держу свое приложение открытым (идеальное состояние) в течение 15-20 минут, тогда соединение теряется, поэтому я использую ping-manger для решения этой проблемы.

Есть ли какой-нибудь другой лучший способ сделать это или ping manager - единственный вариант?

4 ответа

Решение

Лучший способ сохранить живое соединение с XMPP-сервером - подключаться после каждого изменения сети.

Как этот открытый класс 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;
}

}

Заставил пинговать чат-сервер постоянно, вам лучше пользоваться ConnectionListener() в библиотеке чмока. Вам нужно использовать что-то вроде этого:

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?
      }
    });

Да, есть. Несколько баллов перед решением

  1. Сделайте свой сервис ЛИПКИМ, с уведомлением переднего плана, так как это будет необходимо для работы на или после Build.VERSION_CODES.O
  2. Этот липкий сервис, вы должны запускаться при каждой загрузке, через BOOT_COMPLETED намеренное действие и запуск этой службы переднего плана от получателя.
  3. Да, теперь он всегда там, теперь вы всегда можете пойти для проверки вашего соединения
  4. Ты можешь использовать google-volley для создания соединений, и даже вы можете общаться с помощью него.
  5. На это нет хорошей документации, но мне она очень нравится, так как она работает безупречно после успешного добавления зависимости.
  6. Добавление этой зависимости займет время, поскольку я сказал, что нет хорошей документации..

Для связи:

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);

Вам просто нужно ответить ECHO "SUCCESS" с сервера, используя php (или любой другой язык на стороне сервера, который вам нравится). В ответ проверьте на SUCCESS наличие, любые другие случаи.., используйте другие ключевые слова, которые вам нравятся. Вы можете handle Server response errors too, Даже вы можете общаться с Android в запросе - ответ рукопожатие. Но вы должны реализовать несколько рукопожатие самостоятельно.

Я надеюсь, что это помогает...

Используйте класс ReconnectionManager, как описано здесь.

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

Он будет автоматически переподключен при необходимости.

Другие вопросы по тегам