XMPP总的来说就是:基于XML数据结构,点对点的,及时通讯协议

是 Linux操作系统+Apache软件+mySql数据库 + php 编程语言 组成

 

开始时要导入 XMPPFrameWork框架:【附带框架如下】

 

具体的框架下载地址:http://pan.baidu.com/s/1hqoB4pQ

 

如果要搭建XMPP开发环境 可以从下面获取一些必要的安装软件:

 

我把需要安装的软件都已经整理好了,下次给大家分享一下如何搭建的问题:

 

安装好环境接下来就进入最有意思的环节写代码:

 

 

首先将值之前下载的框架引入我们的文件中:

 

 

引入完框架接下来县创建一个XMPPManager的类用来放置通道管理器:XMPPStream

,用户类:XMPPRoster和XMPP的CoreData储存的类:并创建登陆和注册方法获取用户名和密码:

 

具体代码如下:

 

 

// 1、通道管理器类  在服务器之间创建通道
@property(nonatomic,strong)XMPPStream * XMPPStream;// 好友关系(好友花名册,添加好友信息)2、 用户类
@property(nonatomic,strong)XMPPRoster * XMPPRoSter;// 这两个属性是聊天记录用到的
// XMPP的CoreData存储的类

@property(nonatomic,strong)XMPPMessageArchiving * achivimg;@property(nonatomic,strong)NSManagedObjectContext * context;// 创建单例 放进不会重复初始化的东西+(instancetype)defaultManager;// 登陆-(void)loginWithUserName:(NSString *)userName andPassWorld:(NSString *)password;// 注册-(void)registerWithUserName:(NSString *)userName andPassword:(NSString *)password;

在XMPPManager的.m文件中还需要使用一个XMPPJID的类来记录用户的一些信息,主要的工作是对通道管理器类进行初始化,设置自己的服务器名,设置端口号遵循

XMPPStreamDelegate,XMPPRosterDelegate这两个代理。初始化方法如下:

 

-(id)init{self = [super init];if (self) {// 初始化自己的通道管理器类
        self.XMPPStream =[[XMPPStream alloc]init];// 服务器的名字,(在openfire后台管理里面看)
        self.XMPPStream.hostName = @"127.0.0.1";// 设置端口号, 默认是5222self.XMPPStream.hostPort = 5222;// 设置代理在主线程里面
        [self.XMPPStream addDelegate:self delegateQueue:(dispatch_get_main_queue())];XMPPRosterCoreDataStorage * coreDataStorage =[XMPPRosterCoreDataStorage sharedInstance];// 初始化用户管理self.XMPPRoSter = [[XMPPRoster alloc]initWithRosterStorage:coreDataStorage dispatchQueue:(dispatch_get_main_queue())];// 在主线程中添加代理方法
        [self.XMPPRoSter addDelegate:self delegateQueue:(dispatch_get_main_queue())];// 将用户类放进通道管理器类里面
        [self.XMPPRoSter activate:self.XMPPStream];XMPPMessageArchivingCoreDataStorage * coreData = [XMPPMessageArchivingCoreDataStorage sharedInstance];self.achivimg =[[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:coreData dispatchQueue:(dispatch_get_main_queue())];// 将消息类放进管理器通道类里面
        [self.achivimg activate:self.XMPPStream];self.context = coreData.mainThreadManagedObjectContext;}return self;
}

接着实现代理方法:

通道管理器类作为一个信息传输的通道,需要每次进行连接,在连接的同时我们可以通过JID获取用户的信息实现具体的连接类用来获取用户数:

 

 

-(void)connectionWithUserName:(NSString *)userName andPassWord:(NSString *)passwod{// 在发生登录注册的时候,需要让我的通道类连接断掉,防止出现连接混乱的情况if ([self.XMPPStream isConnected]) {// 仅允许一个终端在线登录(不允许重复登录)
        [self.XMPPStream disconnect];}self.password = passwod;// 3、XMPPJId 保存的是一些用户的信息// 这个类当这个通道和服务器连接,保存的是一些用户的信息// 可以知道是给别人发消息,还是别人发来的消息
XMPPJID * jid =[XMPPJID jidWithUser:userName domain:@"127.0.0.1" resource:@"iOS"]; // 可以知道是发送消息还是接收消息// 在jid保存到XMPPStream里面self.XMPPStream.myJID = jid;// 让通道管理器类建立连接
    [self.XMPPStream connectWithTimeout:1.0f error:nil];}

除此之外要使用代理中的方法,判断连接的状态,这也是使用管理器连接成功的关键:

代理方法如下:

 

// 当连接成功
-(void)xmppStreamDidConnect:(XMPPStream *)sender
{switch (self.myConnectMode) {case connectIsLogin:[self.XMPPStream authenticateWithPassword:self.password error:nil];break;case connectIsRefister:[self.XMPPStream registerWithPassword:self.password error:nil];break;default:break;}}

// 连接失败-(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{}

// 将要失去连接-(void)xmppStreamWillConnect:(XMPPStream *)sender
{}

 

这样基本上我们就把我们的XMPPManager类给写好了接下来就是登录和注册页面:

 

可以简单的使用storyboard将登录和注册页面拖拽出来:

使用storyboard时应该有三点需要注意的尤其对于新手来讲:首先如果存在代理,遵循代理(比如tableView),接着要记得绑定相应的页面,最后记得设置storyboard Id

 

在登录和注册页面中都要遵循 <XMPPStreamDelegate>代理:并将其放进主线程中

在注册页面中主要实现的方法有:

登录成功执行的方法主要是为了想服务器发送上线的消息

// 登录成功执行的方法
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{// 连接成功后发送消息,发送有效消息,上线消息XMPPPresence * presence =[XMPPPresence presenceWithType:@"available"];// 上线的消息通过XMPPStream 发送
    [[XMPPManager defaultManager].XMPPStream sendElement:presence];NSLog(@"登录成功");AppDelegate * app = [UIApplication sharedApplication].delegate;RootViewController * roster =[[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"rootVC"];app.window.rootViewController = roster;}

当点击登录按钮时需要将用户的用户名和密码发送

 

 

- (IBAction)LoginAction:(id)sender {// 调用XMPPManager里面的登录注册的方法// 调用XMPP里面的登录注册的方法获取用户名密码
    [[XMPPManager defaultManager]loginWithUserName:self.nameTextFild.text andPassWorld:self.passwordTextFild.text];}

在注册的界面中主要要实现的方法是:

注册成功的方法:

-(void)xmppStreamDidRegister:(XMPPStream *)sender
{UIAlertView * alertView =[[UIAlertView alloc]initWithTitle:@"提示" message:@"恭喜您注册成功" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];[alertView show];LoginViewController * longinVC =[[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"loginVC"];[self showViewController:longinVC sender:nil];}

之后登录注册页面就这样简单的完成了,做好了登录和注册就想发送消息就想把冬天的那句暖暖的问候发送给你,但是我需要知道你的信息才行,接下来我们可以建立用户的好友列表界面:

在好友列表界面中要遵循<XMPPRosterDelegate>用户类的代理方法,主要实现的方法包括:

// 获取好友列表-(void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item
{// 通过获取好友列表这个方法有助于获得各个好友的信息,通过item获取if ([[[item attributeForName:@"subscription"]stringValue]isEqualToString:@"both"]) {// 获取item里面节点的数据NSString * jidStr =[[item attributeForName:@"jid"]stringValue];// 通过在item里面获取到的数据初始化一个XMPPJIDXMPPJID * jid =[XMPPJID jidWithString:jidStr];// 把这个jid放到数据源数组里面
        [self.dataArray addObject:jid];// 使界面中的信息能够自动下翻[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.dataArray.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];}
}

还有两个好友列表的代理方法根据需要来实现:

/ 开始获取好友列表-(void)xmppRosterDidBeginPopulating:(XMPPRoster *)sender
{NSLog(@"开始获取");
}// 结束获取好友列表-(void)xmppRosterDidEndPopulating:(XMPPRoster *)sender
{NSLog(@"结束获取");
}

 

有了你的信息我就想加你为好友接下来在XMPPManager里面设置加好友的方法:

// 收到好友的请求的代理方法-(void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence
{// 获取来自于好友的请求self.fromJID = presence.from;// 弹框
    UIAlertView * view =[[UIAlertView alloc]initWithTitle:@"收到好友请求" message:@"加我为好友吧~~" delegate:self cancelButtonTitle:@"残忍拒绝" otherButtonTitles:@"乐意加入", nil];[view show];}

根据自己的选择实现UIAlertView的代理方法来进行好友的添加:

 

 

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{switch (buttonIndex) {case 0:// 拒绝来自fromJID的加入
            [self.XMPPRoSter rejectPresenceSubscriptionRequestFrom:self.fromJID];break;// 接受来自fromJID的数据case 1:[self.XMPPRoSter acceptPresenceSubscriptionRequestFrom:self.fromJID andAddToRoster:YES];break;default:break;}
}

 

有了好友,接下来就是做信息处理了我们在建立一个MessageViewController用来处理信息:

首先在MessageViewController设置一个JID的属性确定和我聊天的是谁

接着在.m文件中需要实现的代理方法有:

首先我们要在CoreData中获取数据:

 

// 获取发送的信息数据
-(NSArray *)findData
{NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];NSEntityDescription *entity = [NSEntityDescription entityForName:@"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:[XMPPManager defaultManager].context];[fetchRequest setEntity:entity];// Specify criteria for filtering which objects to fetch//bareJidStr 参数代表的是和我聊天的人//streamBareJidStr 参数代表的是我自己NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bareJidStr = %@ AND streamBareJidStr = %@",  self.toJid.bare, [XMPPManager defaultManager].XMPPStream.myJID.bare];[fetchRequest setPredicate:predicate];// Specify how the fetched objects should be sortedNSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timestamp"ascending:YES];[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];NSError *error = nil;NSArray *fetchedObjects = [[XMPPManager defaultManager].context executeFetchRequest:fetchRequest error:&error];if (fetchedObjects == nil) {// 查询的数据不存在则返回一个数组return [NSArray array];}else{// 返回查询的数据return fetchedObjects;}}

接着就设置接收消息的方法:

 

 

// 接收消息时
-(void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{[self.dataArray removeAllObjects];[self.dataArray setArray:[self findData]];[self.tableView reloadData];// 代码自动滚动[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:self.dataArray.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];}

发送消息是的代理方法:

// 发送时遵循的代理-(void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message
{[self.dataArray removeAllObjects];[self.dataArray setArray:[self findData]];[self.tableView reloadData];// 代码自动滚动[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:self.dataArray.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

这样我们的消息类也处理完成了,运行程序可以看到:

 

首先是保证我们的服务器都已经开启:

接着注册

 

然后点击注册:

接着登陆

此时点击登陆后我们跳转到的是好友列表界面因为没有添加好友所以目前是空的

 

我们打开Spark登陆我们之前在服务器中注册的一个账号

添加windsSunShine为好友:

此时我们的模拟器会收到邀请信息:

选择加入就成功添加好友,然后点击聊天就可以把你的问候传递给你的朋友啦~~~

具体的代码可以上我的GitHub上下载欢迎点星:

 欢迎转载,请注明转载和原文出处:http://www.cnblogs.com/windsSunShine/p/4986234.html

转载于:https://www.cnblogs.com/windsSunShine/p/4986234.html

给我一个及时的问候——XMPP相关推荐

  1. XMPP iOS客户端实现三:登录、注册

    1.创建一个单例模式来管理xmpp的连接和操作 1 +(XMPPManager *)share 2 { 3 static XMPPManager *_share=nil; 4 static dispa ...

  2. 物联网应用层协议选择和分析--MQTT、CoAP 、HTTP、XMPP、SoAP

    物联网应用层协议选择和分析--MQTT.CoAP .HTTP.XMPP.SoAP MQTT协议 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)最早 ...

  3. python实现第一个web_使用Python的Flask框架来搭建第一个Web应用程序

    1.初始化在这章,你将学到Flask应用程序的不同部分.同时,你将编写和运行你的第一个Flask web应用程序. 所有的Flask应用程序都必须创建一个 应用程序实例 .使用web服务器网关接口协议 ...

  4. 转:XMPP协议、MQTT协议、HTTP协议、CoAP协议的基本比较

    一.先看下相关国外的专业数据对四大协议的比较: Protocol                                    CoAP                         XMP ...

  5. 关于 IMPP/XMPP/SIMPLE 这几种即时通讯协议和NAT traversal

    IM(Instant Messaging)正在被广泛地采用,特别是在公司与它们的客户互动联接方案上.为了解决即时通讯的标准问题,IETF成立了专门的工作小组,研究和开发与IM相关的协议. 目前IM有四 ...

  6. xmpppy获取服务器版本信息,为什么XMPP? - 今幕明的个人页面 - OSCHINA - 中文开源技术交流社区...

    为什么XMPP? 在研究XMPP与红隼利用激励因素是被终止虚拟机的问题不作任何清除或信号,机器将离开泳池.XMPP提供用于确定是否一个机器被连接到池的基础设施.它也提供了用于共享连接的机器(空闲,忙碌 ...

  7. XMPP与SIP-IM两大协议的对比

    2019独角兽企业重金招聘Python工程师标准>>> XMPP与SIP-IM两大协议的对比 XMPP 协议简介 Google 通过官方宣布,Google Talk 将正式支持不同I ...

  8. Android 模块 -- 基于XMPP协议的手机多方多端即时通讯方案

    目   录 基于XMPP协议的手机多方多端即时通讯方案................................................................. 1 目   录 ...

  9. Android基于XMPP Smack openfire 开发的聊天室

    公司刚好让做即时通讯模块,服务器使用openfire,偶然看到有位仁兄的帖子,拷贝过来细细研究,感谢此仁兄的无私,期待此仁兄的下次更新 转自http://blog.csdn.net/lnb333666 ...

最新文章

  1. 跨界创新,智启未来 | 清华大学大数据研究中心2021年RONG奖学金答辩会成功举办...
  2. vmware虚拟机redhat7.2下docker容器安装hadoop
  3. 158行代码!程序员复现DeepMind图像生成神器
  4. mysql 结束符报错_【踩坑记录】MySQL 实现自定义递归函数
  5. 3.2 Spring AOP的设计与实现
  6. 苹果罕见人事大调整:多个项目被迫暂停 员工“惊慌失措”
  7. ChaiNext:ETH上行1900上方
  8. Ubuntu14.04安装build-essential失败,包依赖问题如何解决?
  9. 解决edge浏览器中idm插件不能自动捕捉下载链接的问题
  10. DLL文件_DLLMain函数详解
  11. 景区门票预约系统_九寨沟景区:门票已预约到5月4日
  12. 与64位版本的Windows不兼容,masm运行不了
  13. 《大数据时代》读后感,维克托
  14. 京东后台模板导入SKU报格式错误
  15. html中文字不自动换行 white-space style
  16. 51单片机生成二维码
  17. 美通企业日报 | 特步签约林书豪进军篮球领域;中兴和中国移动直播中国首个5G运动会...
  18. 高等数学(第七版)同济大学 习题12-1 个人解答
  19. 如何说服导师放你去实习?
  20. 实验三+163+张玉洁

热门文章

  1. [译]CSS3实现柱状图的3D立体动画效果
  2. 企业级SpringBoot教程 (十)用spring Restdocs创建API文档
  3. BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
  4. 具体解释http 协议
  5. Scala 深入浅出实战经典 第81讲:Scala中List的构造是的类型约束逆变、协变、下界详解...
  6. windows下面常用的***测试命令
  7. Real Application Cluster 10g安装与配置(下)
  8. 运行control userpasswords2实现winXP自动登录
  9. qr分解求线性方程组_矩阵分解
  10. Layui或Layuimini整合Echarts 5