Xmpp學習之Smack發送消息JID變亂碼


Xmpp學習之Smack發送消息JID變亂碼

版權聲明:本文為博主原創文章,未經博主允許不得轉載。

轉載請表明出處:http://www.cnblogs.com/cavalier-/p/6947723.html

快速導航,簡單來個目錄圖片。

圖片

前言

上一篇博客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的優先級明顯高於PLAINDIGEST-MD5X-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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM