Xmpp断线重连
相关资料
http://blog.youkuaiyun.com/h7870181/article/details/12499955#1
http://www.open-open.com/lib/view/open1387327663015.html
在android基于openfire服务器,Asmack开源框架的即时通讯应用。做断线重连机制。
思路
- 开启服务XmppService在后台长时间监听
- 在服务XmppService的onStart()中设置监听事件,如果xmpp断开则,打开定时器
- 在定时器中判断,如果有网络就重新连接,如果没有网络,继续走定时器,在后台5s判断一次
- 最终如果有了网络就再次连接服务器
- 在服务销毁的时候关闭定时器
代码如下
package com.pad.diabetesrecord.service;
import java.util.Timer;
import java.util.TimerTask;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.XMPPConnection;
import com.pad.diabetesrecord.commen.utils.NetWorkUtil;
import com.pad.diabetesrecord.commen.utils.ToastUtils;
import com.pad.diabetesrecord.push.XmppConnection;
import com.pad.diabetesrecord.push.XmppUtils;
import com.pad.diabetesrecord.receiver.OpenfirePushReceive;
import com.pad.diabetesrecord.task.LoginTask;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class XmppService extends Service {
private XMPPConnection con;
private Timer timer;
private MyTimertask timetask;
private final IBinder binder = new MyBinder();
private static XmppService mInstance = null;
Context context;
public class MyBinder extends Binder {
public XmppService getService() {
return XmppService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return binder;
}
public static XmppService getInstance() {
return mInstance;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
context=this;
}
class MyTimertask extends TimerTask {
@Override
public void run() {
// TODO Auto-generated method stub
if (NetWorkUtil.isnetWorkAvilable(context)) {
System.out.println(".....正在连接中");
synchronized (ACCESSIBILITY_SERVICE) {
new LoginTask(OpenfirePushReceive.context).execute();
}
login();
}else{
System.out.println("xmpp 当前没有网络");
timer.schedule(new MyTimertask(), 5000);
}
}
}
void login() {
System.out.println("xmpp is listener");
con = XmppConnection.getConnection();
con.addConnectionListener(new ConnectionListener() {
@Override
public void connectionClosed() {
// TODO Auto-generated method stub
System.out.println("xmpplistener----connectionClosed");
XmppConnection.closeConnection();
timer = new Timer();
timer.schedule(new MyTimertask(), 5000);
}
@Override
public void connectionClosedOnError(Exception e) {
// TODO Auto-generated method stub
// 这里就是网络不正常或者被挤掉断线激发的事件
XmppConnection.closeConnection();
System.out.println("xmpplistener----connectionClosedOnError");
System.out.println("xmpplistener----error" + e.getMessage());
timer = new Timer();
timer.schedule(new MyTimertask(), 5000);
}
// 重新连接失败
@Override
public void reconnectionFailed(Exception arg0) {
// TODO Auto-generated method stub
}
// 重新连接的动作正在进行的动作,里面的参数arg0是一个倒计时的数字,
// 如果连接失败的次数增多,数字会越来越大,开始的时候是14
@Override
public void reconnectingIn(int arg0) {
System.out.println("xmpplistener----xmpp 连接倒计时 " + arg0);
}
// 当网络断线了,重新连接上服务器触发的事件
@Override
public void reconnectionSuccessful() {
System.out
.println("xmpplistener----reconnectionSuccessful重新连接成功");
}
});
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
System.out.println("service----onStart");
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
login();
}
}).start();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (timetask != null) {
timetask.cancel();
}
}
}
xmpp连接配置
package com.pad.diabetesrecord.push;
import java.io.File;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.provider.PrivacyProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smackx.GroupChatInvitation;
import org.jivesoftware.smackx.PrivateDataManager;
import org.jivesoftware.smackx.bytestreams.ibb.provider.CloseIQProvider;
import org.jivesoftware.smackx.bytestreams.ibb.provider.DataPacketProvider;
import org.jivesoftware.smackx.bytestreams.ibb.provider.OpenIQProvider;
import org.jivesoftware.smackx.bytestreams.socks5.provider.BytestreamsProvider;
import org.jivesoftware.smackx.packet.ChatStateExtension;
import org.jivesoftware.smackx.packet.LastActivity;
import org.jivesoftware.smackx.packet.OfflineMessageInfo;
import org.jivesoftware.smackx.packet.OfflineMessageRequest;
import org.jivesoftware.smackx.packet.SharedGroupsInfo;
import org.jivesoftware.smackx.provider.AdHocCommandDataProvider;
import org.jivesoftware.smackx.provider.DataFormProvider;
import org.jivesoftware.smackx.provider.DelayInformationProvider;
import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
import org.jivesoftware.smackx.provider.DiscoverItemsProvider;
import org.jivesoftware.smackx.provider.MUCAdminProvider;
import org.jivesoftware.smackx.provider.MUCOwnerProvider;
import org.jivesoftware.smackx.provider.MUCUserProvider;
import org.jivesoftware.smackx.provider.MessageEventProvider;
import org.jivesoftware.smackx.provider.MultipleAddressesProvider;
import org.jivesoftware.smackx.provider.RosterExchangeProvider;
import org.jivesoftware.smackx.provider.StreamInitiationProvider;
import org.jivesoftware.smackx.provider.VCardProvider;
import org.jivesoftware.smackx.provider.XHTMLExtensionProvider;
import org.jivesoftware.smackx.search.UserSearch;
import android.os.Build;
public class XmppConnection {
// XMPP连接对象
public static XMPPConnection conn = null;
private static XmppConnection xmppConnection;
private XmppConnection() {
}
public synchronized static XmppConnection getInstance() {
if (xmppConnection == null) {
xmppConnection = new XmppConnection();
}
return xmppConnection;
}
// 单例模式
/**
* 获得XMPP连接对象
*
* @return XMPPConnection XMPP连接对象
*/
public XMPPConnection getConnection() {
if (conn == null) {
openConnection();
}
return conn;
}
/**
* 关闭XMPP连接
*/
public void closeConnection() {
if (conn.isConnected()) {
System.out.println("---------xmpp将要关闭");
conn.disconnect();
}
conn = null;
}
/**
* 建立XMPP连接
*
* @return 连接建立成功,返回true;否则返回false
*/
private boolean openConnection() {
// 建立连接配置信息对象
ConnectionConfiguration connConfig = new ConnectionConfiguration(
XmppContacts.XMPP_HOST, XmppContacts.XMPP_PORT,
XmppContacts.XMPP_NAME);
// 允许重复连接
connConfig.setReconnectionAllowed(true);
// 其他配置
connConfig.setSendPresence(false);
connConfig
.setSecurityMode(ConnectionConfiguration.SecurityMode.enabled);
connConfig.setDebuggerEnabled(XmppContacts.XMPP_DEBUG_MODEL); // 调试模式
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
connConfig.setTruststoreType("AndroidCAStore");
connConfig.setTruststorePassword(null);
connConfig.setTruststorePath(null);
} else {
connConfig.setTruststoreType("BKS");
String path = System.getProperty("javax.net.ssl.trustStore");
if (path == null)
path = System.getProperty("java.home") + File.separator + "etc"
+ File.separator + "security" + File.separator
+ "cacerts.bks";
connConfig.setTruststorePath(path);
}
// 创建连接对象
conn = new XMPPConnection(connConfig);
try {
conn.connect();
// 配置各种Provider
configureConnection(ProviderManager.getInstance());
return true;
} catch (XMPPException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return false;
}
/**
* XMPP配置信息
*/
private static void configureConnection(ProviderManager pm)
throws ClassNotFoundException {
// Private Data Storage
pm.addIQProvider("query", "jabber:iq:private",
new PrivateDataManager.PrivateDataIQProvider());
// Time
pm.addIQProvider("query", "jabber:iq:time",
Class.forName("org.jivesoftware.smackx.packet.Time"));
// Roster Exchange
pm.addExtensionProvider("x", "jabber:x:roster",
new RosterExchangeProvider());
// Message Events
pm.addExtensionProvider("x", "jabber:x:event",
new MessageEventProvider());
// Chat State
pm.addExtensionProvider("active",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("composing",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("paused",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("inactive",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
pm.addExtensionProvider("gone",
"http://jabber.org/protocol/chatstates",
new ChatStateExtension.Provider());
// XHTML
pm.addExtensionProvider("html", "http://jabber.org/protocol/xhtml-im",
new XHTMLExtensionProvider());
// FileTransfer
pm.addIQProvider("si", "http://jabber.org/protocol/si",
new StreamInitiationProvider());
pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams",
new BytestreamsProvider());
pm.addIQProvider("open", "http://jabber.org/protocol/ibb",
new OpenIQProvider());
pm.addIQProvider("close", "http://jabber.org/protocol/ibb",
new CloseIQProvider());
pm.addExtensionProvider("data", "http://jabber.org/protocol/ibb",
new DataPacketProvider());
// Group Chat Invitations
pm.addExtensionProvider("x", "jabber:x:conference",
new GroupChatInvitation.Provider());
// Service Discovery # Items //解析房间列表
pm.addIQProvider("query", "http://jabber.org/protocol/disco#items",
new DiscoverItemsProvider());
// Service Discovery # Info //某一个房间的信息
pm.addIQProvider("query", "http://jabber.org/protocol/disco#info",
new DiscoverInfoProvider());
// Data Forms
pm.addExtensionProvider("x", "jabber:x:data", new DataFormProvider());
// MUC User
pm.addExtensionProvider("x", "http://jabber.org/protocol/muc#user",
new MUCUserProvider());
// MUC Admin
pm.addIQProvider("query", "http://jabber.org/protocol/muc#admin",
new MUCAdminProvider());
// MUC Owner
pm.addIQProvider("query", "http://jabber.org/protocol/muc#owner",
new MUCOwnerProvider());
// Delayed Delivery
pm.addExtensionProvider("x", "jabber:x:delay",
new DelayInformationProvider());
// Version
try {
pm.addIQProvider("query", "jabber:iq:version",
Class.forName("org.jivesoftware.smackx.packet.Version"));
} catch (ClassNotFoundException e) {
// Not sure what's happening here.
}
// VCard
pm.addIQProvider("vCard", "vcard-temp", new VCardProvider());
// Offline Message Requests
pm.addIQProvider("offline", "http://jabber.org/protocol/offline",
new OfflineMessageRequest.Provider());
// Offline Message Indicator
pm.addExtensionProvider("offline",
"http://jabber.org/protocol/offline",
new OfflineMessageInfo.Provider());
// Last Activity
pm.addIQProvider("query", "jabber:iq:last", new LastActivity.Provider());
// User Search
pm.addIQProvider("query", "jabber:iq:search", new UserSearch.Provider());
// SharedGroupsInfo
pm.addIQProvider("sharedgroup",
"http://www.jivesoftware.org/protocol/sharedgroup",
new SharedGroupsInfo.Provider());
// JEP-33: Extended Stanza Addressing
pm.addExtensionProvider("addresses",
"http://jabber.org/protocol/address",
new MultipleAddressesProvider());
pm.addIQProvider("si", "http://jabber.org/protocol/si",
new StreamInitiationProvider());
pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams",
new BytestreamsProvider());
pm.addIQProvider("query", "jabber:iq:privacy", new PrivacyProvider());
pm.addIQProvider("command", "http://jabber.org/protocol/commands",
new AdHocCommandDataProvider());
pm.addExtensionProvider("malformed-action",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.MalformedActionError());
pm.addExtensionProvider("bad-locale",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.BadLocaleError());
pm.addExtensionProvider("bad-payload",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.BadPayloadError());
pm.addExtensionProvider("bad-sessionid",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.BadSessionIDError());
pm.addExtensionProvider("session-expired",
"http://jabber.org/protocol/commands",
new AdHocCommandDataProvider.SessionExpiredError());
}
}