美文网首页
(十)即时通讯之XMPPFramework登陆注册

(十)即时通讯之XMPPFramework登陆注册

作者: 音符上的码字员 | 来源:发表于2016-08-20 17:11 被阅读490次

    前言

    这也是本人第一次琢磨关于即时通讯方面的内容,结合网上查看的相关资料搭建出来的仿微信小demo,如有意见请多多指教

    写了这么多,尼玛终于到正题了,前面9篇讲的都是基本概念及相关环境的搭建,这里列举一下:

    • Sokcet套接字的简介
    • 网络七层协议,TCP/UDP的概念
    • CocoaSocket的使用
    • XMPP协议的简介
    • XMPP通讯环境SQL的搭建
    • XMPP通讯环境服务器openfire的搭建
    • XMPP通讯环境客户端message,Aduim,Spark的搭建
    • XMPPFramework框架的导入及简单介绍

    具体项目可以在githubWeiChat下载进行查看,如若各位看官老爷觉得还可以请点star

    下面开始进入正题
    XMPPFramework的使用

    看图

    • 用户注册


      注册.gif
    • 登陆


      登陆
    • 切换用户登陆


      切换用户登陆.gif
    • 注销


      注销

    今天讲的是XMPP的登陆注册部分,废话不多说:

    1.登陆注册部分常用的对象

    • XMPPStream XMPP通道:负责XMPP信息的传输以及传输状态等
    • XMPPReconnect 自动连接

    2.准备工作

    1.创建一个单例类名为XMPPManager,负责XMPP相关管理工作,比如各类登陆注册模块的激活,实现都在这里进行处理.
    2.创建一个单例类名为UserManager,负责用户的账号密码的管理以及获取用户信息等方面.

    3.登录注册实现部分

    3.1实现原理

    这里阐述下实现原理,具体实现过程请参考下部分代码以及项目内容.

     1.导入XMPPStream,XMPPReonnect头文件
     2.激活XMPPStream,XMPPReconnect模块并设置代理
     3.登录的流程:
      xmpp的登录流程是,
      3.1 传递 JID , Host , Port 先连接上服务器 
      3.2连接成功了 再 发送密码到服务器 ,
      3.3授权成功 或者 授权失败.这就代表登陆成功或失败,成功了则跳到微信主界面
    
     4.注册的流程:
       4.1xmpp的注册流程是, 传递 JID , Host , Port 先连接上服务器 :
    通过JID连接成功
    连接成功则会自动调用XMPPStreamDelegatexmppStreamDidConnect 代理方法
    然后在通过代理方法调用 XMPPStream的发送密码的方法authenticateWithPassword
       4.2连接成功了 再 发送注册密码到服务器 
       4.3注册成功 或者 失败,注册成功了跳到登陆界面,进行登陆
    
    共同点:
    不管你jid存不存在 都能连接到服务器。
    
    不同点:
    发送的是授权密码 还是 发送注册密码 就是决定你是登录还是注册.
    5.在登陆注册页面进行调用方法并传递状态
    

    注意:
    1.连接到服务器后,对于是登陆还是注册的判断
    2.登陆成功后需要发送一个在线状态消息,离线了需要发送离线状态消息
    3.在UserManager中登陆用户信息和注册用户信息分清楚
    4.XMPPStream代理方法执行的顺序先后
    5.block对于登陆注册状态的提示
    6.对于XMPP JID的理解,用户名@服务器地址.设备信息(可选)

    详细请看demo
    7.这个demo里登录名就是密码,不影响使用,请注意

    3.2XMPPManager部分

    3.2.1单例类
    #pragma mark 创建XMPPManager单例类
    singleton_m(manager)
    
    3.2.2创建XMPPStream对象
    // 登录注册什么的都是和服务器交互,所以我们用到的类就是XMPPStream
    - (void)connect {
        if (!self.stream) {
            // 创建XMPPStream,只需要初始化一次,所以加判断
            self.stream = [[XMPPStream alloc] init];
            // 设置stream的域名和端口号
            self.stream.hostName = kHostName;
            self.stream.hostPort = kHostPort;
            // 添加代理 连接成功后调用传密码的方法
            [self.stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    
    // 连接服务器
    - (void)connectToServer {
        // 判断是否连接成功过
        if (![self.stream isConnected]) {
            // 连接到服务器
            NSError *error;
            [self.stream connectWithTimeout:XMPPStreamTimeoutNone error:&error];
            if (error) {
                NSLog(@"%@",error);
            } else {
                // 连接成功则会自动调用XMPPStreamDelegatexmppStreamDidConnect 代理方法
                // 然后在通过代理方法调用 XMPPStream的发送密码的方法authenticateWithPassword
                NSLog(@"连接成功");
            }
        }
    }
    
    3.2.3 用户登陆,使用登陆JID用户名
    - (void)xmppUserLogin:(UserSatateBlock)block {
        // block赋值给全局变量,在代理方法中调用block传递登陆信息
        self.block = block;
        
        // 不管登陆几次,每次登陆之前都要先把连接断开
        [self.stream disconnect];
        
        // 初始化XMPPPStream
        [self connect];
        
        /**
         *  因为在调用之前,在userDefault中存储的是登陆用户的名字
            所以在这里获取用户的名字
         */
        UserManager *user = [UserManager sharedmanager];
        [user readLoginInfo];
        // 设置XMPPStream的JID   : yoyu@127.0.0.1.iPhone
        self.stream.myJID = [XMPPJID jidWithUser:user.loginName domain:kHostName resource:@"iPhone"];
        
        // 通过读取UserDefault中的name连接服务器
        [self connectToServer];
    }
    
    3.2.4用户注册,使用注册JID用户名
    - (void)xmppUserRegist:(UserSatateBlock)block {
        self.block = block;
        
        // 不管登陆几次,每次登陆之前都要先把连接断开
        [self.stream disconnect];
        
        // 初始化XMPPPStream
        [self connect];
        
        /**
         *  因为在调用之前,在userDefault中存储的是注册用户的名字
            所以在这里获取用户的名字
         */
        UserManager *user = [UserManager sharedmanager];
        [user readRegistInfo];
        // 设置XMPPStream的JID   : yoyu@127.0.0.1.iPhone
        self.stream.myJID = [XMPPJID jidWithUser:user.registName domain:kHostName resource:@"iPhone"];
        
        // 通过读取UserDefault中的name连接服务器
        [self connectToServer];
    }
    
    3.2.5用户注销
    - (void)xmppUserLogout {
        // 发送离线状态
        [self sendOfflineMessage];
        
        // 断开连接
        [self.stream disconnect];
        
        // 跳转到登陆界面
        UIWindow *window = [[UIApplication sharedApplication].delegate window];
        UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"LoginAndRegist" bundle:nil];
        window.rootViewController = [storyBoard instantiateInitialViewController];
    }
    
    3.2.6XMPPStreamDelegate连接服务器状态
    #pragma mark -- XMPPStreamDelegate
    /**
     *  登录的流程:
        xmpp的登录流程是, 传递 JID , Host , Port 先连接上服务器 ,连接成功了 再 发送密码到服务器 ,授权成功 或者 授权失败
     
        注册的流程:
        xmpp的注册流程是, 传递 JID , Host , Port 先连接上服务器 ,连接成功了 再 发送注册密码到服务器 ,注册成功 或者 失败
     
        共同点:
        不管你jid存不存在 都能连接到服务器。
     
        不同点:
        发送的是授权密码 还是 发送注册密码 就是决定你是登录还是注册
    
     */
    /**
        通过JID连接成功
     *  连接成功则会自动调用XMPPStreamDelegatexmppStreamDidConnect 代理方法
        然后在通过代理方法调用 XMPPStream的发送密码的方法authenticateWithPassword
     */
    #pragma mark -- 连接成功
    - (void)xmppStreamDidConnect:(XMPPStream *)sender {
        NSLog(@"通过JID建立连接成功");
        /**
         *  发送密码进行授权登陆
            分登陆密码
            和注册密码
            需要判断
         */
        UserManager *user = [UserManager sharedmanager];
        //[user readUserInfo];
        NSError *error = nil;
        NSLog(@"%@",user.loginName);
        NSLog(@"---%@",user.registName);
        if (user.loginName) {
            // 发送登陆密码
            [self.stream authenticateWithPassword:user.loginPsw error:&error];
        } else {
            // 发送注册密码
            [self.stream registerWithPassword:user.registPsw error:&error];
        }
    }
    
    #pragma mark -- 连接失败,与服务器断开连接(例如网络原因)
    - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error {
        NSLog(@"通过JID建立连接失败,与服务器断开连接");
        if (self.block) {
            self.block(XMPPUserStateTypeOther);
        }
        
        // 发送通知:状态2表示连接服务器失败
        [[NSNotificationCenter defaultCenter] postNotificationName:kLoginStateNotification object:nil userInfo:@{@"state":@"3"}];
    }
    
    3.2.7XMPPStreamDelegate登陆
    /**
     *  属于登陆方面
     */
    #pragma mark -- 授权登陆成功
    -(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
        NSLog(@"授权登陆成功");
        if (self.block) {
            self.block(XMPPUserStateTypeSuccess);
        }
        
        // 授权登陆成功后,跳转到主界面
        UIWindow *window = [[UIApplication sharedApplication].delegate window];
        UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        window.rootViewController = [storyBoard instantiateInitialViewController];
        
        // 同时要发送一个在线的信息
        [self sendOnlineMessage];
    }
    
    #pragma mark -- 授权登陆失败
    -(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
        NSLog(@"授权登陆失败");
        if (self.block) {
            self.block(XMPPUserStateTypeFaild);
       }
    }
    
    3.2.8XMPPStreamDelegate注册
    /**
     *  属于注册方面
     */
    #pragma mark -- 注册成功
    - (void)xmppStreamDidRegister:(XMPPStream *)sender{
        NSLog(@"注册成功");
        if (self.block) {
            self.block(XMPPUserStateTypeSuccess);
        }
    }
    
    #pragma mark -- 注册失败
    - (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error{
        NSLog(@"注册失败");
        if (self.block) {
            self.block(XMPPUserStateTypeFaild);
        }
    }
    
    3.2.7登陆状态发送
    #pragma mark ******************************
    #pragma mark - 登陆成功后,给服务器发送一个在线消息:上线了
    /**
        presence表示用户状态
     
       presence 的状态:
            available 上线
            away 离开
            do not disturb 忙碌
            unavailable 下线
     */
    - (void)sendOnlineMessage {
        /**
         *  关于用户的上线和下线,需要用到一个类XMPPPresence 类。这个类是XMPPElement的子类,主要用来管理某些信息的展现。首先要实例化一个对象,这其中会用到一个presenceWithType 方法,有两个选择@"unavailable"代表下线,@"available"代表上线,一般情况上线的时候后面就可以直接省略。
         */
        XMPPPresence *pre = [XMPPPresence presenceWithType:@"available"];
        // XMPPPresence *pre = [XMPPPresence presence];
        [self.stream sendElement:pre];
    }
    
    #pragma mark - 离线时,给服务器发送一个在线消息:下线了
    - (void)sendOfflineMessage {
        XMPPPresence *pre = [XMPPPresence presenceWithType:@"unavailable"];
        [self.stream sendElement:pre];
    }
    

    3.3登陆注册页面
    这个部分就不详细介绍了,可以进demo查阅

    未完待续...

    相关文章

      网友评论

          本文标题:(十)即时通讯之XMPPFramework登陆注册

          本文链接:https://www.haomeiwen.com/subject/breisttx.html