在Android中保持与Xmpp服务器连接的最佳方法

4

我正在开发一个聊天应用程序,使用ejabberd saas版作为xmpp服务器。我正在使用smack库的ver-4.2.3版本。为了保持连接活跃,我正在使用ping管理器。以下是我使用的代码:

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-service来进行连接,但当我将应用程序保持打开状态(理想状态)15-20分钟后,连接会丢失,因此我正在使用ping管理器来解决此问题。

除了ping管理器之外,还有其他更好的方法吗?


我建议你学习使用流管理的 Conversation project。请参考 XmppConnection - Chathura Wijesinghe
4个回答

3

不要持续地向聊天服务器发送ping请求,最好使用Smack库中的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?
      }
    });

2
是的,有的。解决方案前需要注意以下几点:
  1. 使服务具有STICKY属性,在 Build.VERSION_CODES.O 版本之后,需要前台通知才能正常工作。
  2. 应该在每次启动时启动此 STICKY 服务,并通过 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);

您只需要使用 PHP(或其他服务器端语言)从服务器回复ECHO "SUCCESS"。在响应中检查是否存在SUCCESS,以及其他情况下使用您喜欢的关键字。您可以处理服务器响应错误。甚至可以在请求-响应握手中从 Android 进行通信。但是您必须自己实现几个握手过程。

希望这能帮到您...


感谢您的快速回复!这怎么能代替ping管理器?我们必须保持与Ejabberd XMPP服务器的连接活动,而不是与我们的服务器的连接。在smack中,我们有一个PingManager来实现这一点。 - Snehangshu Kar

2

为了保持与XMPP服务器的连接,最好在每次网络变化后重新连接。

就像这样:

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

}

1
以上的代码用于重新连接服务器,使用Android闹钟管理器或Smack Ping管理器来保持活动状态,以便您可以向服务器发送出席信息。 - Shavareppa
1
谢谢Shavareppa,我使用了Alarm Manager而不是Ping Manager,现在它可以工作了。但是在连接服务器时我会丢失一些消息。 - Snehangshu Kar

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接