XMPP是一种基于标准通用标记语言的子集XML的协议,它继承了在xml环境中灵活的发展性。
XMPP中定义了3个角色:客户端、服务器、网关。通信能够在这三者的任意两个之间双向发生。服务器同时承担了客户端的信息记录,连接管理和信息的路由功能。网关承担着与异构即时通讯系统的互联互通,异构系统可以包括SMS、MSN、ICQ等。基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在智商传输XML。
XMPP的使用:
1、XMPP初始化:
//设置添加好友为“挂起”状态
Roster.setDefaultSubscriptionMode(SubscriptionMode.manual);
//初始化ConnectionConfiguration,参数是服务器ip,端口号及服务器名称
ConnectionConfiguration config = new ConnectionConfiguration(ILove.XMPP_HOST,
ILove.XMPP_PORT, ILove.XMPP_SERVICE_NAME);
//是否允许自动连接
config.setReconnectionAllowed(false);
//初始连接对象XMPPConnection
XMPPConnection conn = new XMPPTCPConnection(config);
conn.setPacketReplyTimeout(PACKET_REPLY_TIMEOUT_SEC * 1000);
//添加连接监听
conn.addConnectionListener(mConnectionListener);
//添加消息监听
conn.addPacketListener(mMessagePacketListener, mMessagePacketListener.makePacketFilter());
conn.addPacketListener(mSubscriptionPacketListener,
mSubscriptionPacketListener.makePacketFilter());
conn.addPacketListener(mCloudIPacketListener, mCloudIPacketListener.makePacketListener());
conn.addPacketListener(mJinglePacketListener, mJinglePacketListener.makePacketFilter());
//黑名单
PrivacyListManager manager = PrivacyListManager.getInstanceFor(conn);
manager.addListener(mPrivacyListListener);
// xep-0184自动回复
DeliveryReceiptManager.getInstanceFor(conn).setAutoReceiptsEnabled(true);
2、重写这几个监听事件
(1)连接监听事件
class AccountConnectionListener implements ConnectionListener{
//只说明connectionClosedOnError方法,其它方法不作说明
//主要是因为这个方法判断是否存在同一账号在不同设备登录的问题
@Override
public void connectionClosedOnError(Exception e) {
Log.i(TAG, "connectionClosedOnError" + "," + e.getMessage());
String errStr = e.getMessage();
if (errStr.matches(".*conflict.*")) {
mController.exit(null);
// 重复登陆
Handler handler = new Handler(Looper.getMainLooper());
handler.post(
new Runnable() {
@Override
public void run() {
Intent intent = new Intent(mApplication, LoginHomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
mApplication.startActivity(intent);
ToastCustom.showToast(mApplication, "账号在其他设备登录", null, Toast.LENGTH_SHORT, true);
}
}
);
} else {
mController.notifyLoginedAccountNetworkStatus(Account.this);
mExecutor.execute(new Runnable() {
@Override
public void run() {
registerReconnection();
}
});
}
}
}
(2)消息监听事件(只拿其中一个来说)
class MessagePacketListener implements PacketListener {
public PacketFilter makePacketFilter() {
return new PacketFilter() {
@Override
public boolean accept(Packet packet) {
if (packet instanceof Message) {
Message message = (Message) packet;
String from = message.getFrom();
String to = message.getTo();
String body = message.getBody();
MessageAttachment attachment = message.getExtension(MessageAttachment.ELEMENT, MessageAttachment.NAMESPACE);
if ((TextUtils.isEmpty(body) && attachment == null)
|| TextUtils.isEmpty(from) || TextUtils.isEmpty(to)) {
return false;
}
if (message.getExtension(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE) != null) {
// received消息直接丢弃
// request消息由DeliveryReceiptManageryou自动回复
return false;
}
if (message.getType().equals(Message.Type.chat)) {
return true;
} else if (message.getType().equals(Message.Type.normal)) {
return true;
} else if (message.getType().equals(Message.Type.error)) {
return true;
} else if (message.getType().equals(Message.Type.headline)) {
return true;
}
}
return false;
}
};
}
@Override
public void processPacket(Packet packet) throws NotConnectedException {
Message msg = (Message) packet;
String body = msg.getBody();
if (msg.getType().equals(Message.Type.chat)) {
// 普通消息
mController.receiveMessageExt(Account.this, msg);
} else if (msg.getType().equals(Message.Type.error)) {
if ("wait".equalsIgnoreCase(msg.getError().getType().toString()) && "resource-constraint".equalsIgnoreCase(msg.getError().getCondition())) {
//消息未发送成功
mController.receiveErrorMessageFailed(getUsername(), msg);
} else {
// 消息被屏蔽通知
mController.receiveErrorMessage(getUsername(), msg);
}
} else if (msg.getType().equals(Message.Type.normal)) {
String subject = msg.getSubject();
if ("NewSystemMessage".equals(subject)) {
// 系统社区通知
mController.newSystemMessage(Account.this, body);
} else {
// 系统消息
mController.receiveMessageExt(Account.this, msg);
}
} else if (msg.getType().equals(Message.Type.headline)) {
Log.d(TAG, "HeadLine typed message : " + msg.getSubject());
if ("new-gift".equals(msg.getSubject())) {
// 暂时放在这里,如果以后有新的消息类型再做统一管理
ForumAccount.getInstance(mApplication).setHasNewGiftHeadline(true);
} else if ("new-announce".equals(msg.getSubject())) {
ForumAccount.getInstance(mApplication).setHasNewAnnounceHeadline(true);
}
}
}
}
3、XMPP连接:
conn.connect;
4、XMPP登录:
conn.login(String username, String password, String s);
5、XMPP注销
conn.disconnect;