環信(XMPP)

一、即時通訊

什么是即時通訊?

  • 即時通訊,又稱實時通訊
  • 即時通信(Instant Messaging,簡稱IM)是一個實時通信系統,允許兩人或多人使用網絡實時的傳遞文字消息、文件、語音與視頻交流
  • 即時通訊在開發中使用的場景
    • 開發一個類型于微信,QQ,易信的聊天軟件
    • 在電商APP集成買家與賣家的實時溝通等
  • 當前時下,實現即時通訊的方案
    • 1.XMPP
    • 2.環信

二、XMPP

XMPP是什么?

  • (1).XMPP:The Extensible Messaging and Presence
    Protocol(可擴展通訊和表示協議)
  • (2).XMPP是一種基于XML的即時通訊協議,XMPP的官方文檔是RFC 3920
    • 這個文檔定義了登錄,退出,獲取好友,發送消息等等的XML數據傳輸協議
  • (3).XMPP是一個典型的C/S架構,基本的網絡形式是客戶端通過TCP/IP連接到服務器,通過Socket建立連接,然后在之上傳輸XML流
  • (4).XMPP是一種類似于HTTP協議的一種數據傳輸協議,其過程就如同“解包裝 --〉包裝”的過程。只需要理解其接收的類型及返回的類型,便可以很好的利用XMPP來進行數據通訊
  • (5).XMPP官方網站——http://xmpp.org

XMPP實現即時通信的準備工作

1-下載Openfire服務器
2-下載XMPPFramework框架


三、環信

什么是環信?

  • 環信是一個第三平臺,提供即時通信(IM –Instant Messaging )的服務
  • 環信是在XMPP的基礎上進行二次開發
  • 環信在網絡上傳輸的數據也是XML
  • 使用環信,不用自己搭建服務器,節約成本
  • 環信日活30萬以下,永遠免費
  • 2015年上半年易觀發布中國移動IM云報告,環信穩居市場第一
  • 公司如要開發即時通訊軟件,建議首選環信,環信占用市場份額較大
各類IM服務占比例圖的變化.png

集成環信的前提準備

 /*
*registerSDKWithAppKey:區別app的標識,開發者注冊及管理后臺apnsCertName:iOS中推送證書名稱。制作與上傳推送證書
*/

//環信的初始化
//    [[EaseMob sharedInstance] registerSDKWithAppKey:@"MG#MGChat"
ap sCertName:@””];

//環信的初始化
并隱藏日志輸出 
[[EaseMob sharedInstance] registerSDKWithAppKey:@"MG#MGChat" apnsCertName:@"" otherConfig:@{kSDKConfigEnableConsoleLogger:@(NO)}];```

![登錄.png](http://upload-images.jianshu.io/upload_images/1429890-e6764e24a534832b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

- 注冊

[[EaseMob
sharedInstance].chatManager asyncRegisterNewAccount:”MG” password:”123456” withCompletion:^(NSString *username, NSString *password,EMError *eror) {
NSLog(@"error:%@,username:%@,pwd:%@",error,username,password);
} onQueue:nil];```


  • 自動登錄
    • 自動登錄:當然程序再次啟動時,如果用戶已經成功登錄過,不需要用戶再輸入用戶名和密碼進行登錄
    • 實現方法
      (1)把登錄帳號信息保存下來,程序起動發送登錄請求
      (2)環信已經實現了自動登錄,只需要在第一次登錄成功后調用 下面的方法即可
      [[EaseMobsharedInstance].chatManagersetIsAutoLoginEnabled:YES];
  • 總結:不管哪種方法,實質都是再次調用了登錄的網絡請求

  • 掉線自動登錄
    -如果網絡不通過,用戶應該自動連接到服務器,以及時接收消息
    • 此功能無需程序員自己做,環信框架已實現,環信SDK會調用自動連接的代理方法來通知應用程序
/*!
 @method
 @brief 將要發起自動重連操作時發送該回調
 @discussion
 @result
 */
- (void)willAutoReconnect;
 
/*!
 @method
 @brief 自動重連操作完成后的回調(成功的話,error為nil,失敗的話,查看error的錯誤信息)
 @discussion
 @result
 */
- (void)didAutoReconnectFinishedWithError:(NSError*)error;```
***

- 好友
  - 上面的協議的實現了對用戶的基本操作,如
(1)添加好友
(2)從本地獲取好友列表
(3)從服務器獲取最新好友列表
(4)接收好友添加請求
(5)刪除好友
(6)被好友從名單上刪除
***

- 聊天
環信消息發送的流程
1.先把記錄保存到Conversation表
2.接著發送網絡請求,API如下

[[EaseMob sharedInstance].chatManager asyncSendMessage:message progress:self prepare:^(EMMessage *message, EMError *error) {
NSLog(@"prepare %@",message.messageBodies);
} onQueue:nil completion:^(EMMessage *message, EMError *error) {
NSLog(@"完成%@",message.messageBodies);
} onQueue:nil];```

  • 步驟
    ①先獲取EMConversation會話管理者對象
    ②調用EMConversation的
    - (NSArray*)loadNumbersOfMessages:(NSUInteger) aCountbefore:(long long)timestamp;獲取指定的聊天記錄

  • 環信提供會話管理者(EMConversation)來管理未讀消息數和歷史聊天記錄,具體代碼如下

  • 總的未讀消息數需要遍歷conversations

// 1.獲取所有歷史會話
NSArray *conversations = [[EaseMob sharedInstance].chatManager conversations];
 
// 2.如果內存中,沒有會話,從數據庫中加載
if(conversations.count == 0)
{
   conversations = [[EaseMob sharedInstance].chatManager loadAllConversationsFromDatabaseWithAppend2Chat:YES];
}```
![Snip20160421_6.png](http://upload-images.jianshu.io/upload_images/1429890-19ee9e81764f398c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 當進入聊天頁面時,需要設置所有當前會話信息或者設置已經加載的消息為已讀

// 設置當前會話所有消息都為已讀
[self.conversation markAllMessagesAsRead:YES];

//設置某條消息為已讀
[self.conversation markMessageWithId:<#(NSString *)#> asRead:<#(BOOL)#>]```


  • 語言消息
    • 在錄音前導入環信封裝的兩個錄音框架,如圖


      導入錄音的框架.png
    • 剛才導入的兩個框架,已經實現了錄音Api
// 開始錄音 
[[EMCDDeviceManager
sharedInstance]
asyncStartRecordingWithFileName:fileName  completion:^(NSError *error){
         if(error) {
            NSLog(@"failure to start recording");
         }
}];
// 結束錄音
[[EMCDDeviceManager sharedInstance] asyncStopRecordingWithCompletion:^(NSString *recordPath, NSInteger aDuration, NSError *error) {
        NSLog(@"%@",recordPath);
}];```

// 語音對象
EMChatVoice *voice = [[EMChatVoice alloc] initWithFile:filePath displayName:@"audio"];

//消息體 

EMVoiceMessageBody *body = [[EMVoiceMessageBody alloc] initWithChatObject:voice];
EMMessage *message = [[EMMessage alloc] initWithReceiver:self.buddy.username bodies:@[body]];
message.messageType = eMessageTypeChat;// 私聊
// 不加密
message.requireEncryption = NO;
// 播放完成
[[EMCDDeviceManager sharedInstance] asyncPlayingWithPath:filePath completion:^(NSError *error) {
NSLog(@"播放完成%@",error);
}];```


  • 退出(異步方法)
[[EaseMobsharedInstance].chatManagerasyncLogoffWithUnbindDeviceToken:YEScompletion:^(NSDictionary *info, EMError *error) {
      if (!error) {//退出成功
    }else{//退出失敗;

    }
}
onQueue:nil];```
***
***
***
***
***
***
#補充三點總結:
###使用XMPP遇到的問題
  - 發送附件(圖片,語音,文檔…)時比較麻煩
  - XMPP框架沒有提供發送附件的功能,需要自己實現
    - 實現方法,把文件上傳到文件服務器,上傳成功后獲取文件保存路徑,再把附件的路徑發送給好友
***

###XMPP的實現原理
- XMPP是一個即時通訊的協議,它規范了用于即時通信在網絡上數據傳輸格式的,比如登錄,獲取好友列表等等的格式。XMPP在網絡傳輸的數據是XML格式
  - 比如登錄:把用戶名和密碼放在xml的標簽中,傳輸到服務器
- XMPP是一個基于個Socket通過的網絡協議,目的是為了保存長連接,以實現即時通訊功能
- XMPP的客戶端是使用一個XMPPFramework框架實現
- XMPP的服務器是使用Openfire,一個開源的服務器
- 客戶端獲取到服務器發送過來的好友消息,客戶端需要對XML進行解析,使用的解析框架的KissXML框架,而不是NSXMLParser/GDataXML
***

###簡單的說下環信的實現原理
- 環信是一個即時通信的服務提供商
- 環信使用的是XMPP協議,它是再XMPP的基礎上進行二次開發,對服務器Openfire和客戶端進行功能模型的添加和客戶端SDK的封裝,環信的本質還是使用XMPP,基本于Socket的網絡通信
- 環信內部實現了數據緩存,會把聊天記錄添加到數據庫,把附件(如音頻文件,圖片文件)下載到本地,使程序員更多時間是花到用戶即時體驗上
- 環信內部已經實現了視頻,音頻,圖片,其它附件發送功能
- 環信使用公司可以節約時間成本
  - 不需要公司內部搭建服務器
  - 客戶端的開發,使用環信SDK比使用XMPPFramework更簡潔方便
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容