xmpp實現的即時通訊聊天(一)

有稜角的圓發表於2016-08-25

參考網址:http://www.jianshu.com/p/b401ad6ba1a7

     http://www.jianshu.com/p/4edbae55a07f

一、mysql和openfire環境的配置

1.安裝mysql,mac平臺安裝搜尋一下教程很多的,然後安裝視覺化工具mysql-workbench

然後建立資料庫,如下:

 


 


 


 

 

MYSQL Workbench,來配置資料庫

     1>開啟Finder,command + shift + G 

 

 


 


有個紅色的標記說明沒有許可權訪問,只需要右鍵顯示簡介,將鎖開啟,設定一下就行了

 

 


許可權都改為讀與寫

 

 


2>  MYSQL Workbench 中,雙擊“openfire”,它會變成深黑色,表示處於選中狀態。然後點選選單欄的“File”,匯入剛才放到桌面的檔案

 


 

 

 
2.安裝openfire
首先要安裝java環境,具體教程網上很多的,然後下載安裝openfire,

 

然後關閉再重新開啟系統偏好設定,找到openfile,點選開啟,會跳轉到瀏覽器



 

回到瀏覽器中的openfile設定

 


選擇中文簡體

     下面是預設的,一般不用修改,直接繼續就可以了。


直接繼續

 


繼續

下面需要特別注意,建議將圖片放大檢視。

使用者名稱和密碼填mysql裡設定的使用者名稱和密碼。這裡是 root 和 123456


這裡需要重點設定

設定完成後,會要求你重新設定openfire的密碼,然後就可以用使用者名稱和密碼登陸了。

 


 按照我的步驟來,那麼

     Mysql的使用者名稱和密碼是 root    123456

     openfire的使用者名稱和密碼是  admin 123456

 這個是可以自己定義的

      進入openfile設定之後,可以執行修改密碼,新增使用者等操作

 二.登陸註冊配置:

1.匯入xmpp框架:配置工程


匯入靜態庫

加上-lxml2

/usr/include/libxml2 或者 $(SDKROOT)/usr/include/libxml2

如果不用pch檔案的話則需要在報錯的地方加上UIKit標頭檔案

 2.封裝xmppManager類:

xmppManager類:

.h檔案:

#import <Foundation/Foundation.h>
#import "XMPPFramework.h"
/**
 *  該類主要封裝了xmpp的常用方法
 */
@interface XMPPManager : NSObject<XMPPStreamDelegate,XMPPRosterDelegate>
//通訊管道,輸入輸出流
@property(nonatomic,strong)XMPPStream *xmppStream;

//好友管理
@property(nonatomic,strong) XMPPRoster *xmppRoster;

@property(nonatomic,strong) XMPPJID *fromJid;

//
//聊天資訊歸檔
@property(nonatomic,strong)XMPPMessageArchiving *xmppMessageArchiving;
//資訊歸檔的上下文
@property(nonatomic,strong)NSManagedObjectContext *messageArchivingContext;


//單例方法
+(XMPPManager *)defaultManager;
//登入的方法
-(void)loginwithName:(NSString *)userName andPassword:(NSString *)password;
//註冊
-(void)registerWithName:(NSString *)userName andPassword:(NSString *)password;
-(void)logout;

.m檔案:

#import "XMPPManager.h"
typedef NS_ENUM(NSInteger, ConnectServerPurpose)
{
    ConnectServerPurposeLogin,    //登入
    ConnectServerPurposeRegister   //註冊
};
@interface XMPPManager()
//用來記錄使用者輸入的密碼
@property(nonatomic,strong)NSString *password;
@property(nonatomic)ConnectServerPurpose connectServerPurposeType;//用來標記連線伺服器目的的屬性
@end

@implementation XMPPManager

#pragma mark 單例方法的實現
+(XMPPManager *)defaultManager{
    static XMPPManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[XMPPManager alloc]init];
    });
    return manager;
}

#pragma mark init方法重寫
/**
 *  重寫初始化方法是因為在manager一建立就要使用一些功能,
 *    把這些功能放在初始化方法裡面
 */
-(instancetype)init{
    if ([super init]){
   //1.初始化xmppStream,登入和註冊的時候都會用到它
    self.xmppStream = [[XMPPStream alloc]init];
     //設定伺服器地址,這裡用的是本地地址(可換成公司具體地址)
    self.xmppStream.hostName = @"sunjianfeidemacbook-air.local";
//    設定埠號
    self.xmppStream.hostPort = 5222;
//    設定代理
    [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
      
        
    //2.好友管理//獲得一個儲存好友的CoreData倉庫,用來資料持久化
        
        XMPPRosterCoreDataStorage *rosterCoreDataStorage = [XMPPRosterCoreDataStorage sharedInstance];
        //初始化xmppRoster
        self.xmppRoster = [[XMPPRoster alloc]initWithRosterStorage:rosterCoreDataStorage dispatchQueue:dispatch_get_main_queue()];
        //啟用
        [self.xmppRoster activate:self.xmppStream];
        //設定代理
        [self.xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
        //3.儲存聊天記錄
        //初始化一個倉庫
        XMPPMessageArchivingCoreDataStorage *messageStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
        //建立一個訊息歸檔物件
        self.xmppMessageArchiving = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:messageStorage dispatchQueue:dispatch_get_main_queue()];
        //啟用
        [self.xmppMessageArchiving activate:self.xmppStream];
        //上下文
        self.messageArchivingContext = messageStorage.mainThreadManagedObjectContext;
    }
    return self;
}

-(void)loginwithName:(NSString *)userName andPassword:(NSString *)password
{
    //標記連線伺服器的目的
    self.connectServerPurposeType = ConnectServerPurposeLogin;
    //這裡記錄使用者輸入的密碼,在登入(註冊)的方法裡面使用
    self.password = password;
    /**
     *  1.初始化一個xmppStream
        2.連線伺服器(成功或者失敗)
        3.成功的基礎上,伺服器驗證(成功或者失敗)
        4.成功的基礎上,傳送上線訊息
     */
    
    
    // *  建立xmppjid(使用者)
    // *  @param NSString 使用者名稱,域名,登入伺服器的方式(蘋果,安卓等)
   
    XMPPJID *jid = [XMPPJID jidWithUser:userName domain:@"sunjianfeidemacbook-air.local" resource:nil];
    self.xmppStream.myJID = jid;
    //連線到伺服器
    [self connectToServer];

    //有可能成功或者失敗,所以有相對應的代理方法
    
}

#pragma mark xmppStream的代理方法
//連線伺服器失敗的方法
-(void)xmppStreamConnectDidTimeout:(XMPPStream *)sender{
    NSLog(@"連線伺服器失敗的方法,請檢查網路是否正常");
}
//連線伺服器成功的方法
-(void)xmppStreamDidConnect:(XMPPStream *)sender
{
    NSLog(@"連線伺服器成功的方法");
//登入
    if (self.connectServerPurposeType == ConnectServerPurposeLogin) {
        NSError *error = nil;
//        向伺服器傳送密碼驗證 //驗證可能失敗或者成功
        [sender authenticateWithPassword:self.password error:&error];
       // NSLog(@"-----%@",self.password);
    }
//註冊
    else{
        //向伺服器傳送一個密碼註冊(成功或者失敗)
        [sender registerWithPassword:self.password error:nil];
    }
}


//驗證成功的方法
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
    NSLog(@"驗證成功的方法");
    /**
     *  unavailable 離線
       available  上線
       away  離開
       do not disturb 忙碌
     */
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
    [self.xmppStream sendElement:presence];
}
//驗證失敗的方法
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error
{
    NSLog(@"驗證失敗的方法,請檢查你的使用者名稱或密碼是否正確,%@",error);
}


#pragma mark 註冊
-(void)registerWithName:(NSString *)userName andPassword:(NSString *)password{
    self.password = password;
    //0.標記連線伺服器的目的
    self.connectServerPurposeType = ConnectServerPurposeRegister;
    //1. 建立一個jid
    XMPPJID *jid = [XMPPJID jidWithUser:userName domain:@"sunjianfeidemacbook-air.local" resource:nil];
    //2.將jid繫結到xmppStream
    self.xmppStream.myJID = jid;
    //3.連線到伺服器
    [self connectToServer];
}


#pragma mark 註冊成功的方法
-(void)xmppStreamDidRegister:(XMPPStream *)sender{
    NSLog(@"註冊成功的方法");
    
}
#pragma mark 註冊失敗的方法
-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error
{
    NSLog(@"註冊失敗執行的方法");
}

#pragma mark 連線到伺服器的方法
-(void)connectToServer{
    //如果已經存在一個連線,需要將當前的連線斷開,然後再開始新的連線
    if ([self.xmppStream isConnected]) {
        [self logout];
    }
    NSError *error = nil;
    [self.xmppStream connectWithTimeout:30.0f error:&error];
    if (error) {
        NSLog(@"error = %@",error);
    }
}


#pragma mark 登出方法的實現
-(void)logout{
    //表示離線不可用
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
//    向伺服器傳送離線訊息
    [self.xmppStream sendElement:presence];
    //斷開連結
    [self.xmppStream disconnect];
}

// 收到好友請求執行的方法
-(void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence{
    NSLog(@"好友請求.....");
    self.fromJid = presence.from;
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示:有人新增你" message:presence.from.user  delegate:self cancelButtonTitle:@"拒絕" otherButtonTitles:@"OK", nil];
    [alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    
    switch (buttonIndex) {
        case 0:   [self.xmppRoster rejectPresenceSubscriptionRequestFrom:self.fromJid];
            break;
        case 1:   [self.xmppRoster acceptPresenceSubscriptionRequestFrom:self.fromJid andAddToRoster:YES];
            break;
            
        default:   break;
    }
    
}

具體登陸註冊,聊天下一篇繼續........

相關文章