iOS —— XMPP 詳解

iOS - XMPP 的使用

轉載 https://www.cnblogs.com/QianChia/p/6411914.html

1、XMPP

  • XMPP 是一個基於 Socket 通信的即時通訊的協議,它規範了即時通信在網絡上數據的傳輸格式,比如登錄,獲取好友列表等等的格式。XMPP 在網絡傳輸的數據是 XML 格式。

  • 開發架構:

    IM3

  • iOS 框架:XMPPFramework

  • 服務器:Openfire

  • 數據庫:MySQL

2、XMPPFramework 框架簡介

2.1 XMPPFramework 簡介

  • XMPPFramework 是一個 OS X/iOS 平臺的開源項目,使用 Objective-C 實現了 XMPP 協議(RFC-3920),同時還提供了用於讀寫 XML 的工具,大大簡化了基於 XMPP 的通信應用的開發。

2.2 XMPPFramework 結構

  • 1、XMPPFramework 的目錄結構如下:

    IM5

    目錄 說明
    Authentication 授權,與授權驗證相關,如用戶名密碼等
    Categories 分類,XMPP 自己寫的一些分類,尤其是 NSXMLElement+XMPP 擴展是必備的
    Core 核心,這裏是 XMPP 的核心文件目錄,我們最主要的目光還是要放在這個目錄上
    Extensions 擴展,XMPP 的擴展模塊,用於擴展各種協議和各種獨立的功能,其下每個子目錄都是對應的一個單獨的子功能
    Utilities 工具,都是輔助類,我們開發者不用關心這裏
    Vendor 第三方庫,這個目錄是 XMPP 所引用的第三方類庫,我們也不用關心這裏
    • 雖然這裏有很多個目錄,但是我們在開發中基本只關心 Core 和 Extensions 這兩個目錄下的類。

    • 在 Core 中:

      目錄 說明
      XMPPElement 是一個基類,延展出三個子類
      XMPPIQ 請求,用戶登錄,用戶註冊,添加好友等
      XMPPMessage 消息,用來發各種消息等
      XMPPPresence 展現,用戶上線下線提示等
      XMPPStream 流,非常常用,大部分類的加載都在寫在流的懶加載裏
    • 在 Extensions 中:

      目錄 說明
      CoreDataStorage coreData 存儲
      Reconnect 重新連接
      Roster 好友管理
      SystemInputActivityMonitor 系統輸入的活動監控
    • 在 Vendor 中:

      文件夾 說明
      CocoaAsyncSocket 異步 Socket
      CocoaLumberjack ⽇志相關
      KissXML XML 解析
  • 2、XMPPFramework 中常用的類:

    說明
    XMPPStream XMPP 基礎服務類
    XMPPRoster 好友列表類
    XMPPUserCoreDataStorageObject 管理用戶的類
    XMPPRosterCoreDataStorage 好友列表(用戶賬號)在 core data 中的操作類
    XMPPvCardCoreDataStorage 好友名片(暱稱,簽名,性別,年齡等信息)在 core data 中的操作類
    XMPPvCardTemp 好友名片實體類,從數據庫裏取出來的都是它
    xmppvCardAvatarModule 好友頭像
    XMPPReconnect 如果失去連接,自動重連
    XMPPRoom 提供多用戶聊天支持
    XMPPPubSub 發佈訂閱
    XMPPMessageArchiving 其中有數據表
    XMPPMessageArchiving_Message_CoreDataObject 取出當前信息的類
  • 3、XMPPFramework 幾個常用到的擴展協議:

    協議 協議簡介
    XEP-0006 使能與網絡上某個 XMPP 實體間的通信
    XEP-0009 在兩個 XMPP 實體間傳輸 XML-RPC 編碼請求和響應
    XEP-0012 最後的活動(判斷上線,離開斷開)
    XEP-0045 多人聊天相關協議
    XEP-0054 名片格式的標準文檔,個人信息設置
    XEP-0060 提供通用公共訂閱功能
    XEP-0065 兩個 XMPP 用戶之間建立一個帶外流,主要用於文件傳輸,sockets5 字節流
    XEP-0066 二進制數據傳輸(特殊信息的發送)
    XEP-0082 日期和時間信息的標準化表示
    XEP-0085 聊天對話中通知用戶狀態,聊天狀態通知
    XEP-0100 表述了 XMPP 客戶端與提供傳統的 IM 服務的代理網關之間交換的最佳實踐
    XEP-0115 廣播和動態發現客戶端、設備、或一般實體能力
    XEP-0136 爲服務端備份和檢索 XMPP 消息定義機制和偏好設置,聊天記錄歸檔
    XEP-0153 用於交換用戶頭像,基於名片的頭像
    XEP-0184 消息送達回執協議
    XEP-0199 XMPP ping 協議(用來 ping 服務器和 ping 自己)
    XEP-0202 用於交換實體間的本地時間信息
    XEP-0203 用於延遲發送
    XEP-0224 引起另一個用戶注意的協議
    XEP-0335 JSON 容器(可能以後某些信息傳輸將用 JSON 格式)
    • XMPP 的擴展協議 Jingle 使得其支持語音和視頻,目前 iOS 尚不支持。

      • iOS 發送附件(圖片,語音,文檔…)時比較麻煩,XMPP 框架沒有提供發送附件的功能,需要自己實現。

      • iOS 發送附件實現方法:

        • 1、將獲取到的圖片/音頻文件通過 base64 加密,直接通過 xmpp 的消息體發送過去,然後解碼。
        • 2、通過 http 請求的方式將圖片/音頻文件上傳到服務器,然後將圖片/音頻文件的下載地址通過 xmpp 消息體發送過去,另外一個客戶端下載。

        • 音頻文件建議轉碼爲 amr,這種格式的音頻文件比較小。

2.3 XMPPJID 類

  • 登錄需要到賬號,而所謂的賬號其實就是用戶唯一標識符(JID),在 XMPP 中使用 XMPPJID 類來表示。

  • JID 一般由三部分構成:用戶名,域名和資源名,格式爲 user@domain/resource,例如:[email protected]/Anthony。對應於 XMPPJID 類中的三個屬性 user、domain、resource。

  • 如果沒有設置主機名(HOST),則使用 JID 的域名(domain)作爲主機名,而端口號是可選的,默認是 5222,一般也沒有必要改動它。

2.4 XMPPStream 類

  • 我們要與服務器連接,就必須通過 XMPPStream 類了,它提供了很多的 API 和屬性設置,通過 socket 來實現的。Verdor 目錄包含了 CocoaAsyncSocket 這個非常有名的 socket 編程庫。XMPPStream 類還遵守並實現了 GCDAsyncSocketDelegate 代理,用於客戶端與服務器交互。

    
     
  • 當我們創建 XMPPStream 對象後,我們需要設置代理,才能回調我們的代理方法,這個是支持 multicast delegate,也就是說對於一個 XMPPStream 對象,可以設置多個代理對象,其中協議是XMPPStreamDelegate。

    
     
  • 而當我們不希望某個 XMPPStream 對象繼續接收到代理回調時,我們通過這樣的方式來移除代理。

    
     
  • 接下來,我們要設置主機和端口,通過設置這兩個屬性。

    
     
  • XMPPStream 有 XMPPJID 類對象作爲屬性,標識用戶,因爲我們後續很多操作都需要到 myJID。

    
     
  • 而管理用戶在線狀態的就交由 XMPPPresence 類了,它同樣被作爲 XMPPStream 的屬性,組合到 XMPPStream 中,後續很多關於用戶的操作是需要到處理用戶狀態的。

    
     

2.5 XMPPStreamDelegate

  • 這個協議是非常關鍵的,我們的很多主要操作都集中在這個協議的代理回調上。它分爲好幾種類型的代理 API,比如授權的、註冊的、安全的等。

    
     

2.6 XMPPIQ 類

  • 消息查詢(IQ)就是通過此類來處理的了。XMPP 給我們提供了 IQ 方便創建的類,用於快速生成 XML 數據。

    
     
  • IQ 是一種請求/響應機制,從一個實體發送請求,另外一個實體接受請求並進行響應。例如,Client 在 stream 的上下文中插入一個元素,向 Server 請求得到自己的好友列表,Server 返回一個,裏面是請求的結果。

  • <type></type> 有以下類別(可選設置如:<type>get</type>

    type 說明
    get 獲取當前域值。類似於 http get 方法
    set 設置或替換 get 查詢的值。類似於 http put 方法
    result 說明成功的響應了先前的查詢。類似於 http 狀態碼 200
    error 查詢和響應中出現的錯誤
  • 下面是一個 IQ 例子:

    
     

2.7 XMPPPresence 類

  • 這個類代表節點,我們通過此類提供的方法來生成 XML 數據。presence 它代表用戶在線狀態。

    
     
  • presence 用來表明用戶的狀態,如:online、offline、away、dnd (請勿打擾) 等。當改變自己的狀態時,就會在 stream 的上下文中插入一個 Presence 元素,來表明自身的狀態。要想接受 presence 消息,必須經過一個叫做 presence subscription 的授權過程。

  • <type></type> 有以下類別(可選設置如:<type>subscribe</type>):

    type 說明
    available 上線
    unavailable 下線
    away 離開
    do not disturb 忙碌
    subscribe 訂閱其他用戶的狀態
    probe 請求獲取其他用戶的狀態
    unavailable 不可用,離線(offline)狀態
  • <show></show> 節點有以下類別,如 <show>dnd</show> :

    show 說明
    chat 聊天中
    away 暫時離開
    xa eXtend Away,長時間離開
    dnd 勿打擾
  • <status></status> 節點

    • 這個節點表示狀態信息,內容比較自由,幾乎可以是所有類型的內容。常用來表示用戶當前心情,活動,聽的歌曲,看的視頻,所在的聊天室,訪問的網頁,玩的遊戲等等。
  • <priority></priority> 節點

    • 範圍 -128~127。高優先級的 resource 能接受發送到 bare JID 的消息,低優先級的 resource 不能。優先級爲負數的 resource 不能收到發送到 bare JID 的消息。
  • 發送一個用戶在線狀態的例子:

    
     

2.8 XMPPMessage 類

  • XMPPMessage 是 XMPP 框架給我們提供的,方便用於生成 XML 消息的數據。

    
     
  • message 是一種基本 推送 消息方法,它不要求響應。主要用於 IM、groupChat、alert 和 notification 之類的應用中。

  • <type></type> 有以下類別(可選設置如:<type>chat</type>):

    type 說明
    normal 類似於 email,主要特點是不要求響應
    chat 類似於 qq 裏的好友即時聊天,主要特點是實時通訊
    groupchat 類似於聊天室裏的羣聊
    headline 用於發送 alert 和 notification
    error 如果發送 message 出錯,發現錯誤的實體會用這個類別來通知發送者出錯了
  • <body></body> 節點

    • 所要發送的內容就放在 body 節點下
  • 消息節點的例子:

    
     

3、XMPPFramework 框架使用

3.1 CocoaPods 導入框架

  • 1、通過 CocoaPods 導入第三方框架 XMPPFramework。

    • 在 Podfile 文件中加入如下代碼,在終端中,使用命令 pod install 下載添加 XMPPFramework 框架。

      
       
  • 2、在需要使用 XMPPFramework 的文件中導入以下頭文件。

    
     

3.2 導入框架過程中問題解決

  • 1、用 Cocoapods 集成 XMPPFramework 遇 Module 'KissXML' not found 等問題解決方法。

    • 一般來說,通過 Coacopods 集成集成第三方框架,不會再有依賴庫方面的問題,所以需要檢查導入方式是否正確,最終找到原因,仔細看 githup 上導入說明

      
       
    • 因此,Podfile 裏必須寫入這一句

      
       
  • 2、Xcode8 之後 XMPP 重定義 Redefinition of module 'dnssd' 問題解決方法。

    • 在升級 Xcode 到 8 之後,原來的關於 XMPP 的項目運行報錯,錯誤信息爲: Redefinition of module 'dnssd'。系統和XMPP框架同時用到了 'dnssd',大概就是錯誤的原因。

    • 解決方案:

      
       
  • 3、在 pod update 的過程中有的童鞋會遇到下面這樣的錯誤。

    IM6

    • 這個是因爲更新的 XMPP 框架中支持的最低版本爲 iOS 8.0 / macOS 10.8。The minimum deployment target is iOS 8.0 / macOS 10.8.

    • 把 Podfile 文件中

      
       
      • 的 7.0 改爲 8.0 或以上。
  • 4、pod 更新完成了,出現下面這樣的錯誤。

    IM7

    • 到報錯的工程裏面搜一下

      
       
      • 改成相反的值就行了,別改沒有報錯的工程。

4、XMPPFramework 實現簡單聊天

  • 聊天實現的原理就是,一個客戶端通過 XMPP 協議把信息傳給服務器,服務器再發消息發給另一個客戶端。

4.1 用戶註冊

  • 初始化

    
     
  • 與服務器建立鏈接

    
     
  • 進行註冊

    
     

4.2 用戶登錄、註銷

  • 初始化

    
     
  • 與服務器建立鏈接

    
     
  • 進行登錄認證

    
     
  • 與服務器斷開鏈接,用戶註銷

    
     
  • 用戶登錄信息本地化存儲

    
     

4.3 好友管理

  • 初始化

    
     
  • 獲取好友列表

    
     
  • 刷新好友列表

    
     
  • 刷新好友狀態

    
     
  • 添加好友

    
     
  • 收到添加好友申請

    
     
  • 刪除好友

    
     

4.4 文本消息管理

  • 初始化

    
     
  • 發送文本消息

    
     
  • 接收文本消息

    
     
  • 消息回執

    • 這個是 XEP-0184 協議的內容。

    • 發送消息時附加回執請求

      
       
    • 收到回執請求的消息,發送回執

      
       

4.5 圖片消息管理

  • 圖片和語音文件發送的基本思路:

    • 先將圖片/語音轉化成二進制文件,然後將二進制文件進行 base64 編碼,編碼成字符串。在即將發送的 message 內添加一個子節點,節點的 stringValue(節點的值)設置這個編碼後的字符串。
    • 然後消息發出後取出消息文件的時候,通過 messageType 先判斷是不是圖片/語音信息,如果是圖片/語音信息先通過自己之前設置的節點名稱,把這個子節點的 stringValue 取出來,應該是一個 base64 之後的字符串。
  • 選擇圖片

    
     
  • 發送圖片消息

    • msgType 自定義消息類型,image:圖片消息,audio:音頻消息
    
     
  • 接收圖片消息

    
     

4.6 語音消息管理

  • 圖片和語音文件發送的基本思路:

    • 先將圖片/語音轉化成二進制文件,然後將二進制文件進行 base64 編碼,編碼成字符串。在即將發送的 message 內添加一個子節點,節點的 stringValue(節點的值)設置這個編碼後的字符串。
    • 然後消息發出後取出消息文件的時候,通過 messageType 先判斷是不是圖片/語音信息,如果是圖片/語音信息先通過自己之前設置的節點名稱,把這個子節點的 stringValue 取出來,應該是一個 base64 之後的字符串。
  • 錄製/播放語音

    
     
  • 發送語音消息

    • msgType 自定義消息類型,image:圖片消息,audio:音頻消息
    
     
  • 接收語音消息

    
     

4.7 心跳檢測

  • 爲了監聽服務器是否有效,增加心跳監聽,用 XEP-0199 協議。

  • 在 XMPPFrameWork 框架下,封裝了 XMPPAutoPing 和 XMPPPing 兩個類都可以使用,因爲 XMPPAutoPing 已經組合進了 XMPPPing 類,所以 XMPPAutoPing 使用起來更方便。

  • 初始化並啓動 ping

    
     
  • 停止 ping

    
     

4.8 自動重連

  • 當意外與服務器斷開連接,自動重新連接上去,並且將上一次的信息自動加上去。

  • 初始化

    
     

5、XMPPFramework 快速登錄

6、XMPPFramework 重連以及其他問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章