Xmpp學習之Smack發送消息JID變亂碼
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
快速導航,簡單來個目錄圖片。

前言
繼上一篇博客Android平台使用Smack后,這次咱們來分享一下在集成過程中SASL認證的一些坑=_=。
在此為后面的smack學習做筆記,以作備忘。
以下是本次采用的Demo環境:
- Openfire 3.8.2
- smack 4.2.1
登錄成功后發現jid變成 亂碼@亂碼
一般發生這種問題,在登錄時是沒問題的,但是當你想發送消息時,你會發現接收消息方的名字居然是亂碼,下面我來說一下為什么會登錄成功,但是發送消息亂碼。
解決方案
解決方案很簡單,僅需在調用connection.Login()函數前先調用SASLAuthentication.blacklistSASLMechanism("ANONYMOUS");,把ANONYMOUS加入黑名單即可,下面我來說一下為什么會發生這種情況。
如何證實
如何證實呢?咱們來看一下連接socket后的第二條報文:
<?xml version='1.0' encoding='UTF-8'?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams"
xmlns="jabber:client" from="im"
id="e26ece26"
xml:lang="en"
version="1.0">
<stream:features>
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">
</starttls>
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
<mechanism>PLAIN</mechanism>
<mechanism>ANONYMOUS</mechanism>
<mechanism>JIVE-SHAREDSECRET</mechanism>
</mechanisms>
<compression xmlns="http://jabber.org/features/compress">
<method>zlib</method>
</compression>
<auth xmlns="http://jabber.org/features/iq-auth"/>
<register xmlns="http://jabber.org/features/iq-register"/>
</stream:features>
從上面的報文可以看到服務器支持的 SASL 認證機制只有三種(你們的服務器不一定和我返回的認證機制一樣,這里只是打個比方),但是當你想設置PLAIN認證方式時,你會在API中發現居然沒有設置唯一認證方式,且無法設置優先級,因為ANONYMOUS的排序比PLAIN的順序前,所以SDK直接返回了ANONYMOUS,下面來看一下SASLAuthentication的Sasl認證是怎么做的:
Iterator<SASLMechanism> it = REGISTERED_MECHANISMS.iterator();
final List<String> serverMechanisms = getServerMechanisms();
、、、
// Iterate in SASL Priority order over registered mechanisms
while (it.hasNext()) {
SASLMechanism mechanism = it.next();
String mechanismName = mechanism.getName();
、、、
、、、
if (serverMechanisms.contains(mechanismName)) {
/* Create a new instance of the SASLMechanism
for every authentication attempt.
return*/
mechanism.instanceForAuthentication(connection,
configuration);
}
通過以上源碼咱們發現,無非就是String.contains()函數進行匹配字符串,那么問題來了,如果ANONYMOUS的排序比PLAIN的順序前,則直接返回ANONYMOUS,怎么看到系統的SASLMechanism排序呢?咱們再來看下面的log:
W/System.err: org.jivesoftware.smack.SmackException:
No supported and enabled SASL Mechanism provided by server.
Server announced mechanisms:
[PLAIN, ANONYMOUS, JIVE-SHAREDSECRET].
Registerd SASL mechanisms with Smack: [
SASL Mech:
SCRAM-SHA-1-PLUS, Prio: 100,
SASL Mech: SCRAM-SHA-1, Prio: 110,
SASL Mech: DIGEST-MD5, Prio: 210,
SASL Mech: PLAIN, Prio: 410,
SASL Mech: X-OAUTH2, Prio: 410,
SASL Mech: ANONYMOUS, Prio: 500,
SASL Mech: EXTERNAL, Prio: 510
]. Enabled SASL mechansisms for this connection: [PLAIN].
Blacklisted SASL mechanisms: [PLAIN, SCRAM-SHA-1-PLUS].
相信大家看到上面的log已經發現問題所在了,Prio是優先級,ANONYMOUS的優先級明顯高於PLAIN、DIGEST-MD5、X-OAUTH2等。
小知識
ANONYMOUS級別官方解釋是,匿名登錄,所以產生的JID是隨機生成的。
結尾
本篇博客簡單描述了如何解決SASL認證的一個小坑,歡迎支持。
引用
最新的smack接入指南鏈接:https://download.igniterealtime.org/smack/docs/latest/documentation/gettingstarted.html/
最新版smack JavaDoc鏈接:https://download.igniterealtime.org/smack/docs/latest/javadoc/
