欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

asmack登录冲突(多端登录冲突)处理 博客分类: android  

程序员文章站 2024-03-24 22:44:04
...

功能:登录冲突;

 

效果:弹出对话框,您的账号在xxx设备登录,您已下载;

 

实现步骤:

asmack给我们提拱了一整套连接错误方案,其中就包括了登录冲突;

开始的时候,我还自己去写了一个,原理是上线的时候发送一个自定义的packet出去告诉登陆上的那个用户下线,后来发现这个方法行不通,因为另一端已经下线了,根本拿不到这条消息。

 

后来我想会不会在ConnectionListener里面就有呢?之前我实现登录的时候密码错误用的是捕获登录失败的时候抛出来的异常,所以这次变聪明了,首先从带异常的方法入手;找到以下两个方法:

 

public void connectionClosedOnError(Exception e)

public void reconnectionFailed(Exception e)

 

然后我知道异常都封装在exception,要获取到消息,只要从这些异常对象里面取就行了。因为是xmpp相关的异常,所以肯定是属于XMPPException;于是我把光标停留在这个类,出现如下提示:

 

 

 org.jivesoftware.smack.XMPPException


A generic exception that is thrown when an error occurs performing an XMPP operation. XMPP servers can respond to error conditions with an error code and textual description of the problem, which are encapsulated in the XMPPError class. When appropriate, an XMPPError instance is attached instances of this exception.

When a stream error occured, the server will send a stream error to the client before closing the connection. Stream errors are unrecoverable errors. When a stream error is sent to the client an XMPPException will be thrown containing the StreamError sent by the server.

Author:
Matt Tucker
See Also:
XMPPError

 

 

最后面有个,同看XMPPError,于是我又把光标停在XMPPError,出现了如下信息:

 

 org.jivesoftware.smack.packet.XMPPError


Represents a XMPP error sub-packet. Typically, a server responds to a request that has problems by sending the packet back and including an error packet. Each error has a code, type, error condition as well as as an optional text explanation. Typical errors are:


--------------------------------------------------------------------------------
 Code XMPP Error Type 
500 interna-server-error WAIT 
403 forbidden AUTH 
400bad-request MODIFY > 
404 item-not-found CANCEL 
409 conflict CANCEL 
501 feature-not-implemented CANCEL 
302 gone MODIFY 
400 jid-malformed MODIFY 
406 no-acceptable MODIFY 
405 not-allowed CANCEL 
401 not-authorized AUTH 
402 payment-required AUTH 
404 recipient-unavailable WAIT 
302 redirect MODIFY 
407 registration-required AUTH 
404 remote-server-not-found CANCEL 
504 remote-server-timeout WAIT 
502 remote-server-error CANCEL 
500 resource-constraint WAIT 
503 service-unavailable CANCEL 
407 subscription-required AUTH 
500 undefined-condition WAIT 
400 unexpected-condition WAIT 
408 request-timeout CANCEL 


Author:
Matt Tucker

 发现了有登录冲突的错误代码,然后我加进去这么一段:

 

 

 

@Override
	public void reconnectionFailed(Exception e) {
		if (!PubUtil.volidateNet(mContext))
			return;

		if (e instanceof XMPPException) {
			XMPPException xe = (XMPPException) e;
			final XMPPError error = xe.getXMPPError();
			int errorCode = 0;
			if (error != null) {
				errorCode = error.getCode();// larosn 0930
				Log.v("IMXmppManager", "连接断开,错误码" + errorCode);
				if (errorCode == 409) {// 被踢下线
					mContext.sendBroadcast(new Intent(
							IMPubConstant.ACTION_LOGIN_CONFLICT));
				} else if (errorCode == 502) {// 与远程服务器断开

				}
			}
		}else
			reconnectionBrodcat(true);
	}

 然而并没啥用,这时候我就把希望放在了剩下的connectionClosedOnError方法中,同时配合xmpp协议看到了登录冲突的时候服务器是返回这个StreamError节点的xml流,我跟踪进去找到了StreamError是org.jivesoftware.smack.packet.StreamError包下的,开始我以为StreamError也是packet,计划用监听packet的方式捕获到这个异常;点击进去源码我傻眼了,这个StreamError不是packet的子类;然后我把目标转向了XMPPException,果然在XMPPException下有这个方法:xe.getStreamError();,这就获取到StreamError了,然后在他下面有errorCode,不过这个是字符串方式,我对比了协议,写了这么一段,然后,it works!

if (e instanceof XMPPException) {
			XMPPException xe = (XMPPException) e;
			final StreamError error = xe.getStreamError();
			String errorCode = "";
			if (error != null) {
				errorCode = error.getCode();// larosn 0930
				Log.v("IMXmppManager", "连接断开,错误码" + errorCode);
				if (errorCode.equalsIgnoreCase("conflict")) {// 被踢下线
					mContext.sendBroadcast(new Intent(
							IMPubConstant.ACTION_LOGIN_CONFLICT));
					return;
				}
			}

 

 

好了,登录冲突的实现就这样完成了。有啥疑问可以在下面提问。尊重作者的劳动成果,装载请注明出处,谢谢;