给我一个及时的问候——XMPP

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";

    // 设置端口号, 默认是5222
        self.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里面获取到的数据初始化一个XMPPJID
        XMPPJID * 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 sorted
    NSSortDescriptor *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上下载欢迎点星:

时间: 2025-01-04 14:41:07

给我一个及时的问候——XMPP的相关文章

TCP/IP,Http,Socket,XMPP的区别

大学学习网络基础的时候老师讲过,网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.通过初步的了解,我知道IP协议对应于网络层,TCP协议对应于传输层,而HTTP协议对应于应用层,三者从本质上来说没有可比性,socket则是对TCP/IP协议的封装和应用(程序员层面上).也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据.关于TCP/IP和HTTP协议的关系,网络有一段比较容易理解的介绍: “我们在传输数据时

XMPP协议及实践

一.XMPP协议 XMPP (Extensible Messaging and Presence Protocol)是一种基于标准通用标记语言的子集XML的协议,它继承了在XML环境中灵活的发展性.因此,基于XMPP的应用具有很强的可扩展性.XMPP的前身是Jabber. 1.XMPP中的几个重要概念: JID:即Jabber ID.xmpp网络有一个或多个地址jid,  [email protected]/study组成:节点.域.资源(带有资源的jid是完整jid,没有资源的jid是裸jid

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

一.先看下相关国外的专业数据对四大协议的比较: Protocol                                    CoAP                         XMPP                                                  RESTful HTTP                                                                 MQTT Transport UDP TCP

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

1.创建一个单例模式来管理xmpp的连接和操作 1 +(XMPPManager *)share 2 { 3 static XMPPManager *_share=nil; 4 static dispatch_once_t onceToken; 5 dispatch_once(&onceToken, ^{ 6 _share=[[XMPPManager alloc] init]; 7 }); 8 return _share; 9 } 10 -(id)init 11 { 12 if (self=[su

XMPP协议扩展:XEP-0198 流管理(Stream Management)中文翻译(个人整理,难免有翻译错的地方,请多多指正)

QQ讨论群:172158202 转载原文地址:http://blog.csdn.net/yuedong56/article/details/38120101 xep-0198英文文档链接地址:点击打开链接 RFC 6120中文链接地址:点击打开链接 相关參考1:点击打开链接 1.介绍 XMPP Core 用XMPP定义了流的XML技术(也就是流的建立和终止,包含认证和加密).可是核心的XMPP协议并没有为管理一个灵活的XML流提供工具. Stream Management背后的基本概念是.初始化

开源jabber(XMPP)架设内部即时通讯服务的解决方案

Jabber 是著名的即时通讯服务服务器,它是一个自由开源软件,能让用户自己架即时通讯服务器,可以在Internet上应用,也可以在局域网中应用.    XMPP(可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探测.它在促进服务器之间的准即时操作.这个协议可能最终允许因特网用户向因特网上的其他任何人发送即时消息,即使其操作系统和浏览器不同.XMPP的技术来自于Jabber,其实它是 Jabber的核心协定,所以XMPP有时被误称为Jabber协议

XMPP协议简介

XMPP(Extensible Messageing and Presence Protocol:可扩展消息与存在协议)是目前主流的四种IM(IM:instant messaging,即时消息)协议之一,其他三种分别为:即时信息和空间协议(IMPP).空间和即时信息协议(PRIM).针对即时通讯和空间平衡扩充的进程开始协议SIP(SIMPLE).      在这四种协议中,XMPP是最灵活的.XMPP是一种基于XML的协议,它继承了在XML环境中灵活的发展性.因此,基于XMPP的应用具有超强的可

Asmack开发系列之XMPP概述

这一节,我们从Asmack基于的协议核心出发,XMPP协议,来学习.弄懂XMPP对学习Asmack源码有着重要的原因,做到知其然知其所以然. 本文主要是学习<XMPP The Definitive Guide Building Real-Time Applications with Jabber Technologies>文总结而来. 1,您能够拿XMPP来做什么? XMPP(Extensible Messaging and Presence Protocol),主要是传输XML数据. 典型的

XMPP协议学习笔记一

即时通讯技术简介 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容.大多数常用的即时通讯发送程序都会提供各种各样的功能: 即时通讯 - 在用户和在线朋友之间来回发送信息 聊天 - 创建用户与朋友或工友的自定义聊天室 网页链接 - 共享用户喜爱的网址 支持图片 - 浏览朋友计算机中的图片 支持声音 - 给朋友播放音乐 支持文件传输 - 直接将文件发送给朋友,以便于共享 交谈 - 使用 Internet