android之XMPP过程分析
XMPP协议簇
利用androidpn打印一次完整报文信息 ( 非全部, 个别没有打印)
RCVD: 客户端
<stream:stream to="192.168.0.107" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">
SENT: 服务端
<?xml version='1.0' encoding='UTF-8'?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" from="192.168.0.107" id="2f53e19" xml:lang="en" version="1.0">
SENT: 服务端
<stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"></starttls><auth xmlns="http://jabber.org/features/iq-auth"/><register xmlns="http://jabber.org/features/iq-register"/></stream:features>
RCVD: 客户端
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
RCVD: 客户端
<iq id="1m85x-0" type="set"><query xmlns="jabber:iq:register"><password>123456</password><username>123456</username></query></iq>
SENT: 服务端
<iq type="result" id="1m85x-0" to="192.168.0.107/2f53e19"/>
RCVD: 客户端
<iq id="1m85x-1" type="get"><query xmlns="jabber:iq:auth"><username>123456</username></query></iq>
SENT: 服务端
<iq type="result" id="1m85x-1"><query xmlns="jabber:iq:auth"><username>123456</username><password/><digest/><resource/></query></iq>
RCVD: 客户端
<iq id="1m85x-2" type="set"><query xmlns="jabber:iq:auth"><username>123456</username><digest>f123456</digest><resource>AndroidpnClient</resource></query></iq>
SENT: 服务端
<iq type="result" id="1m85x-2" to="123456@192.168.0.107/AndroidpnClient"/>
RCVD: 客户端
<iq id="1m85x-3" type="get"><query xmlns="jabber:iq:roster" ></query></iq>
RCVD: 客户端
<presence id="1m85x-4"></presence>
SENT: 服务端
</stream:stream>
客户端程序
配置文件
apiKey=1234567890
xmppHost=10.176.92.195
xmppPort=5222
连接、文件监听、登录、异常重连
初始化
private void connetionXmpp() {
xmppConnecionListener = new XmppConnecionListener();
ProviderManager.getInstance().addIQProvider("notification", "androidpn:iq:notification",new NotificationIQProvider());
PacketFilter packetFilterNotification = new PacketTypeFilter(
NotificationIQ.class);
PacketFilter packetFilterMessage = new PacketTypeFilter(
org.jivesoftware.smack.packet.Message.class);
orfilter = new OrFilter(packetFilterNotification, packetFilterMessage);
packetListener = new NotificationPacketListener(this);
try {
new Thread() {
public void run() {
try {
conXmpp();
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
} catch (Exception e) {
Log.i("connetionXmpp", e.toString());
}
}
private void conXmpp() {
try {
XMPPConnection xmppConnection = XmppTool.getConnection();
Log.i(TAG,
"xmppConnection.isConnected()"
+ xmppConnection.isConnected());
if (xmppConnection.isConnected()) {
xmppConnection.addConnectionListener(xmppConnecionListener);
xmppConnection.addPacketListener(packetListener, orfilter);
Log.i(TAG, "xmppConnection packetListener success");
FileTransFerListener(xmppConnection);
xmppConnection.login(xmppUsername, xmppPwd, RESOURCE);
Log.i(TAG, "xmppConnection.login success");
} else {
tExit = new Timer();
tExit.schedule(new XmppTimetask(), xmppSpace);
}
} catch (XMPPException e) {
Log.i("connetionXmpp", e.toString());
}
};
文件监听
private void FileTransFerListener(XMPPConnection xmppConnection) {
// FileTransfer
ProviderManager pm = ProviderManager.getInstance();
pm.addIQProvider("si", "http://jabber.org/protocol/si",
new StreamInitiationProvider());
pm.addIQProvider("query", "http://jabber.org/protocol/bytestreams",
new BytestreamsProvider());
pm.addIQProvider("query", "http://jabber.org/protocol/disco#items",
new DiscoverItemsProvider());
pm.addIQProvider("query", "http://jabber.org/protocol/disco#info",
new DiscoverInfoProvider());
ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager
.getInstanceFor(xmppConnection);
if (serviceDiscoveryManager == null)
serviceDiscoveryManager = new ServiceDiscoveryManager(
xmppConnection);
serviceDiscoveryManager
.addFeature("http://jabber.org/protocol/disco#info");
serviceDiscoveryManager.addFeature("jabber:iq:privacy");
FileTransferManager managerListner = new FileTransferManager(
xmppConnection);
managerListner.addFileTransferListener(new FileTransferListenerImp(
getApplicationContext(), handler));
Log.i("File transfere manager", "created");
Log.i(TAG, "xmppConnection fileTransferListener success");
}
连接异常监听
private class XmppConnecionListener implements ConnectionListener {
@Override
public void connectionClosed() {
try {
disConnetionXmpp();
} catch (Exception e) {
Log.i("connectionClosed", e.toString());
} finally {
tExit = new Timer();
tExit.schedule(new XmppTimetask(), xmppSpace);
}
}
@Override
public void connectionClosedOnError(Exception e) {
Log.i("connection", "connectionClosedOnError");
Log.i("connection--", e.toString());
boolean error = e.getMessage().equals("stream:error (conflict)");
if (!error) {
try {
disConnetionXmpp();
} catch (Exception e2) {
Log.i("connectionClosedOnError", e2.toString());
} finally {
tExit = new Timer();
tExit.schedule(new XmppTimetask(), xmppSpace);
}
}
}
@Override
public void reconnectingIn(int seconds) {
Log.i("connection", "reconnectingIn");
}
@Override
public void reconnectionSuccessful() {
Log.i("connection", "reconnectionSuccessful");
}
@Override
public void reconnectionFailed(Exception e) {
Log.i("connection", "reconnectionFailed");
}
}
重连
private class XmppTimetask extends TimerTask {
public XmppTimetask() {
}
@Override
public void run() {
try {
conXmpp();
} catch (Exception e) {
e.printStackTrace();
}
}
}