博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【原】iOS学习42即时通信之XMPP(1)
阅读量:6691 次
发布时间:2019-06-25

本文共 7301 字,大约阅读时间需要 24 分钟。

1. 即时通信

 1> 概述

  即时通讯(Instant Messaging)是目前Internet上最为流行的通讯方式,各种各样的即时通讯软件也层出不穷,服务提供商也提供了越来越丰富的通讯服务功能。

  即时通讯有多种实现方式,例如:XMPP、环信、融云等。

 2> XMPP(可扩展消息处理现场协议)

  XMPP(XML Messages Presence Protocol(可扩展消息处理现场协议))是基于可扩展标记语言(XML)的协议,可用于即时通信(IM)。

 3> XMPP的优点

  • 开放

  XMPP协议是由JSF开源社区组织开发的,不属于任何的机构和个人,从根本上保证了其开放性。

  • 标准

  互联网工程工作组将XMPP于2002年正式列为认可的实时通讯及Presence技术。

  • 分布式的网络架构

  XMPP 协议虽然是基于Client/Server 架构,但是XMPP协议本身并没有这样的限制。网络的架构和电子邮件十分相似,但没有结合任何特定的网络架构,适用范围非常广泛。

  • 具有良好的扩展性

  基于XML 建立起来的应用具有良好的语义完整性和扩展性。

  • 具有很好的弹性

  XMPP 除了可用在即时通信的应用程序,还能用在网络管理、内容供稿、协同工具、档案共享、游戏、远端系统监控等。

  • 安全性

  XMPP在Client-to-Server通信和Server-to-Server通信中都使用TLS (Transport Layer Security)协议作为通信通道的加密方法,保证通信的安全。

  XMPP环境的搭建的步骤详见

2. 工程中添加XMPP

  将XMPP协议第三方文件拖入工程,下载地址:

3. 登录、注册

 1> 界面搭建

  界面采用Storyboard,效果图如下:

 2> 初始化XMPP通道

//初始化通道        self.xmppStream = [[XMPPStream alloc] init];        //openfire服务器IP地址        self.xmppStream.hostName = kHostName;        //openfire服务器端口 默认5222        self.xmppStream.hostPort = kHostPort;        //添加代理        [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()         ];

 3> 连接服务器代码所需方法

 4> 登录代码所需方法

 5> 注册代码所需方法

 

 6> 全部代码(方法的使用详见代码注释)

  • 封装的XMPP控制器代码:

   XMPPManager.h

#import 
#import "XMPPFramework.h"@interface XMPPManager : NSObject/// 声明XMPP通道属性@property (nonatomic, strong) XMPPStream *xmppStream;+ (XMPPManager *)shareXMPPManager;// 登录方法- (void)loginWithUsername:(NSString *)username password:(NSString *)password;// 注册方法- (void)registerWithUsername:(NSString *)username password:(NSString *)password;@end

  XMPPManager.m

#import "XMPPManager.h"static XMPPManager *xmppManager = nil;// 枚举记录状态typedef NS_ENUM(NSUInteger, ConnectToServerPurpose) {    ConnectToServerPurposeLogin,    ConnectToServerPurposeRegister};// 遵循协议@interface XMPPManager () 
/// 用户名@property (nonatomic, copy) NSString *username;/// 密码@property (nonatomic, copy) NSString *password;/// 记录当前的状态,判断是登录还是注册@property (nonatomic) ConnectToServerPurpose connectToServer;@end@implementation XMPPManager+ (XMPPManager *)shareXMPPManager{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ xmppManager = [XMPPManager new]; }); return xmppManager;}#pragma mark - 1.创建通道- (instancetype)init{ self = [super init]; if (self) { //初始化对象 self.xmppStream = [XMPPStream new]; // 设置服务器 [self settingUpServer]; } return self;}// 设置服务器- (void)settingUpServer{ // 设置opfire服务器 self.xmppStream.hostName = kHostName; // 设置服务器端口号 self.xmppStream.hostPort = kHostPort; // 添加代理 [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];}#pragma mark - 登录的方法- (void)loginWithUsername:(NSString *)username password:(NSString *)password{ self.username = username; self.password = password; // 记录登录状态 self.connectToServer = ConnectToServerPurposeLogin; // 连接服务器 [self linkServer];}#pragma mark - 注册的方法- (void)registerWithUsername:(NSString *)username password:(NSString *)password{ self.username = username; self.password = password; // 记录注册状态 self.connectToServer = ConnectToServerPurposeRegister; // 连接服务器 [self linkServer];}#pragma mark - 连接服务器- (void)linkServer{ // 要连接服务器,要有用户身份认证 // 身份证 // 参数1:用户名 // 参数2:域名 // 参数3:资源 XMPPJID *jid = [XMPPJID jidWithUser:self.username domain:kDomin resource:kResource]; self.xmppStream.myJID = jid; // 如果当前聊天工具处于连接状态或已经连接,此时,你需要去切断连接【此逻辑不唯一】 if ([self.xmppStream isConnected] || [self.xmppStream isConnecting]) { // 断开连接 [self disConnectToServer]; } // 设置连接超时 NSError *error = nil; [self.xmppStream connectWithTimeout:30 error:&error]; if (error) { NSLog(@"连接超时"); } }#pragma mark - 断开连接(注销)- (void)disConnectToServer{ // 当前用户不可用(下线了) XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"]; // 告诉通道用户不可用(下线了) [self.xmppStream sendElement:presence]; // 使用通道失去连接 [self.xmppStream disconnect];}#pragma mark - XMPPStreamDelegate协议方法#pragma mark 连接超时- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender{ NSLog(@"连接超时");}#pragma mark 连接成功- (void)xmppStreamDidConnect:(XMPPStream *)sender{ NSLog(@"连接成功"); // 认证密码// [self.xmppStream authenticateWithPassword:self.password error:nil]; // 区分登录和注册进行密码验证 switch (self.connectToServer) { case ConnectToServerPurposeLogin: // 登录认证 [self.xmppStream authenticateWithPassword:self.password error:nil]; break; case ConnectToServerPurposeRegister: // 注册的认证 [self.xmppStream registerWithPassword:self.password error:nil]; break; default: break; }}#pragma mark 断开连接- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error{ // 1. 自己动手断开 // 2. 被动断开 if (error) { NSLog(@"断开连接,error == %@", error); }}#pragma mark 认证失败- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{ NSLog(@"认证失败:error = %@", error);}#pragma mark 认证成功- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{ // 当前用户可用(上线了) XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"]; // 告诉通道用户可用(上线了) [self.xmppStream sendElement:presence]; NSLog(@"认证成功");}@end
  • 登录界面

  LoginViewController.m

#import "LoginViewController.h"#import "XMPPManager.h"@interface LoginViewController ()/// 用户输入框@property (weak, nonatomic) IBOutlet UITextField *usernameTextField;/// 密码输入框@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;@end@implementation LoginViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}- (IBAction)loginAction:(UIButton *)sender{    [[XMPPManager shareXMPPManager] loginWithUsername:self.usernameTextField.text password:self.passwordTextField.text];}@end
  • 注册界面

   RegisterViewController.m

#import "RegisterViewController.h"#import "XMPPManager.h"@interface RegisterViewController () 
@property (weak, nonatomic) IBOutlet UITextField *registerUNTextField;@property (weak, nonatomic) IBOutlet UITextField *registerPWTextField;@end@implementation RegisterViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. // 添加代理 [[XMPPManager shareXMPPManager].xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}// 按钮点击事件- (IBAction)registerAction:(id)sender{ [[XMPPManager shareXMPPManager] registerWithUsername:self.registerUNTextField.text password:self.registerPWTextField.text];}#pragma mark - XMPPStreamDelegate实现协议方法// 注册成功后,dismiss到登录界面- (void)xmppStreamDidRegister:(XMPPStream *)sender{ NSLog(@"注册成功"); [self dismissViewControllerAnimated:YES completion:nil];}// 注册失败- (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error{ NSLog(@"注册失败:%@", error);}@end

 未完待续...

转载于:https://www.cnblogs.com/gfxxbk/p/5504364.html

你可能感兴趣的文章
oo第三次博客作业
查看>>
《结对-结对编项目作业名称-需求分析》
查看>>
iView3.x Anchor(锚点)组件 导航锚点
查看>>
Network --- Tcp Protocol
查看>>
sqlite效率探测
查看>>
React生命周期
查看>>
数据库 -- mysql表操作
查看>>
shutil 高级文件操作
查看>>
Itellij Idea全局搜索
查看>>
Android系统简介
查看>>
配置证书
查看>>
Oracle VM VirtualBox技巧
查看>>
uvm_svcmd_dpi——DPI在UVM中的实现(二)
查看>>
Crimm Imageshop 2.3。
查看>>
SQL AND和OR求值顺序
查看>>
买房必知的五大法律常识 助你安心顺利选房
查看>>
leetcode563
查看>>
剑指Offer 40 最小的k个数
查看>>
winform创建树形菜单的无限级分类
查看>>
017——数组(十七) asort ksort rsort arsort krsort
查看>>