xmpp怎么获取xmpp服务器搭建上所有好友

XMPP搭建本地服务器、实现即时通讯(二) - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了45761字,被350人关注,获得了487个喜欢
XMPP搭建本地服务器、实现即时通讯(二)
前面部分呢,我们实现了一个XMPP本地服务器的搭建
但是我们最终的目的并不是这些,我们是要实现即时通讯的功能,今天我们就在代码里面实现即时通讯的基本功能。
一、项目环境配置
首先我们在工程中导入XMPPFramework
添加本地依赖库:libxml2.tbd和libresolv.tbd
然后Build Settings-&Header searches Pathes添加字段:/usr/include/libxml2
Commend+B编译正常的话就OK了
二、建立与服务器的链接
我们在建立与服务器链接之前需要自己创建:登陆页面,注册页面,好友列表页面和聊天页面,这些在此不再累述,想必大家用可视化,分分钟搞定。至于各个页面之间的关联,更是小kiss我们需要建立一个XMPP的任务管理类对象 而且这个对象只需要一个 我们可以用单例:
#import &Foundation/Foundation.h&
#import "XMPPFramework.h"
@interface XMPPManager : NSObject&XMPPStreamDelegate&
+(XMPPManager *)sharedXMPPM//创建管理者对象单例
@property(nonatomic,strong)XMPPStream *//信息管道
@property(nonatomic,strong)XMPPRoster *xmppR//进行添加好友 删除好友 获取还有列表等功能
@property(nonatomic,strong)XMPPMessageArchiving *xmppMessageA
@property(nonatomic,strong)NSManagedObjectContext *messageManagerC//聊天信息托管对象 上下文
-(void)loginWithUser:(NSString *)user password:(NSString *)
-(void)registWithUser:(NSString *)user password:(NSString *)
#import "XMPPManager.h"
//判断想服务器建立连接是登陆还是注册
typedef enum : NSUInteger {
ConnectToServerPurposeLogin,//登陆
ConnectToServerPurposeRegist,//注册
@interface XMPPManager ()
@property(nonatomic,strong)NSString *//登录密码
@property(nonatomic,strong)NSString *registP//注册密码
@property(nonatomic,assign)MyStatus connectToServerP
@implementation XMPPManager
+(XMPPManager *)sharedXMPPManager{
static XMPPManager *manager =
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
manager = [[XMPPManager alloc]init];
- (instancetype)init
self = [super init];
if (self) {
self.stream = [[XMPPStream alloc]init];
self.stream.hostName = kHostN//服务器的地址
self.stream.hostPort = kHostP//端口号标识唯一的服务
[self.stream addDelegate:self delegateQueue:dispatch_get_main_queue()];//让当前对象成为stream的代理
//进行好友存储
XMPPRosterCoreDataStorage *storage= [XMPPRosterCoreDataStorage sharedInstance];
self.xmppRoster = [[XMPPRoster alloc]initWithRosterStorage:storage dispatchQueue:dispatch_get_main_queue()];
[self.xmppRoster activate:self.stream];//激活
//进行聊天信息存储
XMPPMessageArchivingCoreDataStorage *archiveringStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
self.xmppMessageArchivering = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:archiveringStorage dispatchQueue:dispatch_get_main_queue()];
[self.xmppMessageArchivering activate:self.stream];//激活
self.messageManagerContext = archiveringStorage.mainThreadManagedObjectC
//与服务器建立链接
-(void)connectToServerWithUser:(NSString *)user{
//要是正在链接的话那么就先断开连接
if ([self.stream isConnected]) {
[self disconnectServer];
XMPPJID *jid = [XMPPJID jidWithUser:user domain:kDomin resource:kResource];
self.stream.myJID =
NSError *error =
[self.stream connectWithTimeout:30.0f error:&error];
if (nil != error) {
NSLog(@"%s__%d__链接出错:%@",__FUNCTION__,__LINE__,error);
//与服务器断开链接
-(void)disconnectServer{
[self.stream disconnect];
-(void)loginWithUser:(NSString *)user password:(NSString *)password{
self.connectToServerPurse = ConnectToServerPurposeL
self.password =//将传进来的password传给self.password
[self connectToServerWithUser:user];
-(void)registWithUser:(NSString *)user password:(NSString *)password{
self.connectToServerPurse = ConnectToServerPurposeR
self.registPassword =
[self connectToServerWithUser:user];
#pragma mark--XMPPStreamDelegate
//我们一旦想服务器发送请求之后又两种结果 成功和失败 我们需要实现XMPP协议的两个方法
//与服务器链接成功
-(void)xmppStreamDidConnect:(XMPPStream *)sender{
NSLog(@"%s__%d__",__FUNCTION__,__LINE__);
#pragma mark ------判断与服务器建立连接是登陆还是注册
switch (self.connectToServerPurse) {
case ConnectToServerPurposeLogin:
//建立连接成功之后需要向服务器验证自己的身份
NSError *error =
[self.stream authenticateWithPassword:self.password error:&error];
if (nil != error) {
NSLog(@"%s__%d__验证出错:%@",__FUNCTION__,__LINE__,error);
case ConnectToServerPurposeRegist:
NSError *err =
[self.stream registerWithPassword:self.registPassword error:&err];
if (nil != err) {
NSLog(@"%s__%d__注册出错:%@",__FUNCTION__,__LINE__,err);
//与服务器链接失败
-(void)xmppStreamConnectDidTimeout:(XMPPStream *)sender{
NSLog(@"%s__%d__",__FUNCTION__,__LINE__);
我们在登陆页面点击登陆按钮的时候调用XMPPManager的-(void)loginWithUser:(NSString )user password:(NSString )进行登陆,但是我们在进行登陆的时候是需要服务器的验证的所有这些都直接在代码理显示了,如下:
#import "LoginViewController.h"
#import "XMPPManager.h"
@interface LoginViewController ()&XMPPStreamDelegate&
@property (weak, nonatomic) IBOutlet UITextField *userN
@property (weak, nonatomic) IBOutlet UITextField *userP
@implementation LoginViewController
- (IBAction)loginButton:(id)sender {
//获取用户名和密码
NSString *userName = self.userName.
NSString *userPassword = self.userPassword.
[[XMPPManager sharedXMPPManager]loginWithUser:userName password:userPassword];
- (void)viewDidLoad {
[super viewDidLoad];
[[XMPPManager sharedXMPPManager].stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
// Do any additional setup after loading the view.
#pragma mark--XMPPStreamDelegate
进行身份验证
//验证成功
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
NSLog(@"%s__%d__验证成功",__FUNCTION__,__LINE__);
[[NSUserDefaults standardUserDefaults]setObject:self.userName.text forKey:@"userName"];
[[NSUserDefaults standardUserDefaults]setObject:self.userPassword.text forKey:@"userPassword"];
[[NSUserDefaults standardUserDefaults]synchronize];//立即存储
[self dismissViewControllerAnimated:YES completion:nil];
//验证失败
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
NSLog(@"%s__%d__验证出错:%@",__FUNCTION__,__LINE__,error);
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
此时我们也需要在AppDelegate里面作如下处理,当我们再次打开应用程序的时候要是已经验证成功就显示好友列表页面,否则的话就显示登陆注册页面,由于清一色的代码 给大家来张图缓解一下紧张的气氛吧。
#import "AppDelegate.h"
@interface AppDelegate ()
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (nil == [[NSUserDefaults standardUserDefaults]objectForKey:@"userName"]) {
UIStoryboard *story = [UIStoryboard storyboardWithName:@"LoginAndPregist" bundle:nil];
UINavigationController *nv = [story instantiateInitialViewController];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:nv animated:YES completion:^{
NSString *userName = [[NSUserDefaults standardUserDefaults]objectForKey:@"userName"];
NSString *password = [[NSUserDefaults standardUserDefaults]objectForKey:@"userPassword"];
[[XMPPManager sharedXMPPManager]loginWithUser:userName password:password];
[[XMPPManager sharedXMPPManager].stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
return YES;
#pragma mark--XMPPStreamDelegate
//验证成功
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
NSLog(@"%s__%d__",__FUNCTION__,__LINE__);
//我们验证之后默认的状态是离线的 于是我们想显示在线,需要告诉服务器自己的状态
XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
[[XMPPManager sharedXMPPManager].stream sendElement:presence];
//验证失败
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
其实注册和登陆是有很大的相似性的,例如同样需要遵守XMPPStreamDelegate协议,我们点击注册按钮的时候是会执行XMPPManager的-(void)registWithUser:(NSString )user password:(NSString )进行注册一样的注册成功还是失败都会有相应的方法来执行,
#import "RegistViewController.h"
#import "XMPPManager.h"
@interface RegistViewController ()&XMPPStreamDelegate&
@property (weak, nonatomic) IBOutlet UITextField *userN
@property (weak, nonatomic) IBOutlet UITextField *userP
@implementation RegistViewController
- (IBAction)registButton:(id)sender {
NSString *userName =self.userName.
NSString *userpassword = self.userPassword.
[[XMPPManager sharedXMPPManager]registWithUser:userName password:userpassword];
- (void)viewDidLoad {
[super viewDidLoad];
//设置代理
[[XMPPManager sharedXMPPManager].stream addDelegate:self delegateQueue:dispatch_get_main_queue()];
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
#pragma mark--XMPPStreamDelegate
//注册成功
-(void)xmppStreamDidRegister:(XMPPStream *)sender{
NSLog(@"%s__%d__注册成功",__FUNCTION__,__LINE__);
//注册成功之后返回到登陆界面
[self.navigationController popToRootViewControllerAnimated:YES];
//注册失败
-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error{
NSLog(@"%s__%d__注册失败%@",__FUNCTION__,__LINE__,error);
获取好友列表
获取还有列表我们需要在XMPPManager里面创建一个XMPPRoster对象这个对象具有添加好友 删除好友 获取好友列表等功能
@property(nonatomic,strong)XMPPRoster *xmppR
具体的代码部分 我写的非常详细 大家接着看
#import "RosterTableViewController.h"
#import "XMPPManager.h"
#import "ChatTableViewController.h"
@interface RosterTableViewController ()&XMPPRosterDelegate&
@property(nonatomic,strong)NSMutableArray *rosterA//保存获取的好友
@implementation RosterTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
//初始化数组 这个数组里面保存的是获取的好友
self.rosterArray = [NSMutableArray arrayWithCapacity:10];
[[XMPPManager sharedXMPPManager].xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.rosterArray.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
XMPPJID *jid = self.rosterArray[indexPath.row];
cell.textLabel.text = jid.
#pragma mark--XMPPRosterDelegate
//刚开始获取好友列表
-(void)xmppRosterDidBeginPopulating:(XMPPRoster *)sender{
NSLog(@"%s__%d__",__FUNCTION__,__LINE__);
//正在获取好友列表
-(void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item{
NSLog(@"%s__%d__Item=%@",__FUNCTION__,__LINE__,item);
NSString *jidStr = [[item attributeForName:@"jid"]stringValue];
XMPPJID *jid =[XMPPJID jidWithString:jidStr];
[self.rosterArray addObject:jid];
//将数据添加进数组
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.rosterArray.count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationLeft];
//已经完成获取好友列表
-(void)xmppRosterDidEndPopulating:(XMPPRoster *)sender{
NSLog(@"%s__%d__",__FUNCTION__,__LINE__);
#pragma mark--这个方法的作用是传递一个值到我们需要点击进入的聊天页面,同时在聊天页面设置一个属性值来接收
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UITableViewCell *cell = (UITableViewCell *)
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
XMPPJID *jid = self.rosterArray[indexPath.row];
ChatTableViewController *chat = segue.destinationViewC
chat.chatToJid =
我们在聊天页面开了一个接口,来接受列表页面传进来的XMPPJID
#import &UIKit/UIKit.h&
#import "XMPPManager.h"
@interface ChatTableViewController : UITableViewController
@property(nonatomic,strong)XMPPJID *chatToJ//要聊天的好友
首先,在ChatTableViewController.m里面 我们同样的遵守代理协议XMPPStreamDelegate,定义一个可变数组来接收查询的所有聊天信息
@implementation ChatTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.allMessageArray = [NSMutableArray array];//初始化数组
[[XMPPManager sharedXMPPManager].stream addDelegate:self delegateQueue:dispatch_get_main_queue()];//设置监测对象
[self reloadMessage];
//点击右上角添加按钮传递一条信息
- (IBAction)addButton:(id)sender {
XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.chatToJid];
[message addBody:@"Hello"];
[[XMPPManager sharedXMPPManager].stream sendElement:message];
以下是XMPPStreamDelegate对于信息发送的几个方法
#pragma mark--XMPPStreamDelegate
//发送信息成功
-(void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message{
NSLog(@"%s__%d__",__FUNCTION__,__LINE__);
[self reloadMessage];//发送信息是 刷新一次页面
//发送信息失败
-(void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)message error:(NSError *)error{
NSLog(@"%s__%d__Error:%@",__FUNCTION__,__LINE__,error);
//收到信息
-(void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{
NSLog(@"%s__%d__Message=%@",__FUNCTION__,__LINE__,message);
[self reloadMessage];//收到信息是刷新一次页面
我们在发送消失 或者接收到消失 以及我们进入页面的时候都会显示相应的内容 这其实就设计页面数据加载的内容,因此我们自定义一个方法,用来加载聊天页面的内容,并在相应的方法里进行调用
#pragma mark--加载聊天信息
-(void)reloadMessage{
NSManagedObjectContext *managerObjectContext =[XMPPManager sharedXMPPManager].messageManagerC
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"XMPPMessageArchiving_Message_CoreDataObject" inManagedObjectContext:managerObjectContext];
[fetchRequest setEntity:entity];
// Specify criteria for filtering which objects to fetch
//我们要是不设置相应的检索条件的话 就会吧所有的聊天信息检索出来出来
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bareJidStr == %@ And streamBareJidStr == %@", self.chatToJid.bare,[XMPPManager sharedXMPPManager].stream.myJID.bare];//对方的Jid和自己的Jid
[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 =
NSArray *fetchedObjects = [managerObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
NSLog(@"没有检索出任何内容");
//在此判断一下,因为日要是点击一个人,没有聊天记录的话直接return 否则会崩掉的
if (fetchedObjects.count == 0) {
[self.allMessageArray removeAllObjects];
[self.allMessageArray addObjectsFromArray:fetchedObjects];
[self.tableView reloadData];
//进行信息加载的时候让tableView 滚动到最底部
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.allMessageArray.count-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
至于UITableView data source的几个代理方法就简单的不行不行的了。。。Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.allMessageArray.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Message" forIndexPath:indexPath];
XMPPMessageArchiving_Message_CoreDataObject *message = self.allMessageArray[indexPath.row];
//判断聊天信息是发出去的 还是接受进来的,在cell上显示不一样的样式
if (message.isOutgoing == YES) {
cell.detailTextLabel.text = message.
cell.textLabel.text = @"";
cell.textLabel.text = message.
cell.detailTextLabel.text = @"";
以上就是XMPP实现聊天功能的基本内容,我们在以代码为伍的时候 可以用Openfile和spark等工具帮助我们进行调试~
您觉得这篇文章对您有作用的话 就赏点呗!谢谢 您的鼓励是我创作的源泉
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
如果你是程序员,或者有一颗喜欢写程序的心,喜欢分享技术干货、项目经验、程序员日常囧事等等,欢迎投稿《程序员》专题。
专题主编:小...
· 215756人关注
玩转简书的第一步,从这个专题开始。
想上首页热门榜么?好内容想被更多人看到么?来投稿吧!如果被拒也不要灰心哦~入选文章会进一个队...
· 138847人关注
分享 iOS 开发的知识,解决大家遇到的问题,讨论iOS开发的前沿,欢迎大家投稿~
· 28014人关注
您觉得这篇文章对您有作用的话 就赏点呗!谢谢 您的鼓励是我创作的源泉
选择支付方式:出处:http://blog.csdn.net
接着上一篇文章继续学习和总结。。
XMPP客户端
XMPP 系统的一个设计标准是必须支持简单的客户端。事实上,XMPP 系统架构对客户端只有很少的几个限制。一个XMPP 客户端必须支持的功能有:
通过 TCP 套接字与XMPP 服务器进行通信;
解析组织好的 XML 信息包;
理解消息数据类型。
至于对客户端为何要求如此简单,概括来说就是,xmpp把相关更多功能实现都放在了服务器端去实现和处理,这样使得客户端相对解放出来。。这使得客户端编写变得非常容易,更新系统功能也同样变得容易。
XMPP 客户端与服务端通过XML 在TCP 套接字的5222 端口进行通信,而不需要客户端之间直接进行通信。
基本的XMPP 客户端必须实现以下标准协议(XEP-0211):
RFC3920 核心协议Core
RFC3921 即时消息和出席协议Instant Messaging and Presence
XEP-0030 服务发现Service Discovery
XEP-0115 实体能力Entity Capabilities
XMPP服务器
XMPP 服务器遵循两个主要法则:
监听客户端连接,并直接与客户端应用程序通信;
与其他 XMPP 服务器通信;
不要小看它只需遵循的原则少,这两个原则是所有xmpp服务器的核心与根本,不然,基于xmpp的im根本无从谈起,更别说基于此的模块化扩展了…
XMPP开源服务器一般被设计成模块化,由各个不同的代码包(模块/组件)构成,这些代码包包括但不限于以下:
Session管理
用户和服务器之间的通信
服务器之间的通信
DNS(Domain Name System)转换
存储用户的个人信息和朋友名单
保留用户在下线时收到的信息
用户的身份和权限认证
根据用户的要求过滤信息
另外,服务器可以通过附加服务来进行扩展,如完整的安全策略,允许服务器组件的连接或客户端选择,通向其他消息系统的网关。
基本的XMPP 服务器必须实现以下标准协议
RFC3920 核心协议Core
RFC3921 即时消息和出席协议Instant Messaging and Presence
XEP-0030 服务发现Service Discovery
XMPP 突出的特点是可以和其他即时通信系统交换信息和用户在线状况。由于协议不同,XMPP 和其他系统交换信息必须通过协议的转换来实现,目前几种主流即时通信协议都没有公开,所以XMPP 服务器本身并没有实现和其他协议的转换,但它的架构允许转换的实现。实现这个特殊功能的服务端在XMPP 架构里叫做网关(gateway)。目前,XMPP 实现了和
AIM、ICQ、IRC、MSN Massager、RSS0.9 和Yahoo Massager 的协议转换。由于网关的存在,XMPP 架构事实上兼容所有其他即时通信网络,这无疑大大提高了XMPP 的灵活性和可扩展性。
从这个角度来讲,xmpp网关就是xmpp向外暴露了一个可以兼容其他主流通讯协议的一个接口(某种意义上来说)基于此,我们可以自己实现相应的通信协议来实现xmpp与本协议的相互转换和通信,类似于一个充电器的转换接口,可以适配不同类型的手机一样。
XMPP地址格式
一个实体在XMPP网络结构中被称为一个接点,它有唯一的标示符jabber identifier(JID),即实体地址,用来表示一个Jabber用户,但是也可以表示其他内容,例如一个聊天室.
一个有效的JID包括一系列元素:
域名(domain identifier);
节点(node identifier);
源(resource identifier).
它的格式是
node@domain/resource,
node@domain,类似电子邮件的地址格式.domain用来表示接点不同的设备或位置,这个是可选的,例如a在Server1上注册了一个用户,用户名为doom,那么a的JID就是doom@serverl,在发送消息时,指明doom@serverl就可以了,resource可以不用指定(是可选的),但a在登录到这个Server时,a的JID可能是doom@serverl/exodus(如果a用Exodus软件登录),也可能是doom@serverl/psi(如果a用psi软件登录).资源只用来识别属于用户的位置或设备等,一个用户可以同时以多种资源与同一个XMPP服务器连接。
XMPP消息格式
XMPP中定义了3个顶层XML元素: Message、Presence、IQ
用于在两个jabber用户之间发送信息。Jsm(jabber会话管理器)负责满足所有的消息,不管目标用户的状态如何。如果用户在线jsm立即提交;否则jsm就存储。
To :标识消息的接收方。
from : 指发送方的名字或标示(id)o
Text: 此元素包含了要提交给目标用户的信息
&message to= ‘lily@jabber.org/contact’ type =’chat’&
&body& 你好,在忙吗&/body&
&/message&
用来表明用户的状态,如:online、away、dnd(请勿打扰)等。当用户离线或改变自己的状态时,就会在stream的上下文中插入一个Presence元素,来表明自身的状态.结构如下所示:
&presence&
From =‘lily @ /contact’
To = ‘yaoman @ /contact&
&status& Online &/status&
&/presence&
presence 元素可以取下面几种值:
Probe :用于向接受消息方发送特殊的请求
subscribe:当接受方状态改变时,自动向发送方发送presence信息。
一种请求/响应机制,从一个实体从发送请求,另外一个实体接受请求,并进行响应.例如,client在stream的上下文中插入一个元素,向Server请求得到自己的好友列表,Server返回一个里面是请求的结果.
iq 主要的属性是type。包括:
Get :获取当前域值。
Set :设置或替换get查询的值。
Result :说明成功的响应了先前的查询。
Error: 查询和响应中出现的错误。
结构如下所示:
&iq from =‘lily @ /contact’id=’’ Type=’result’&
再一个例子:
用于确定用户的状态。消息结构举例如下(每个 XML 的 node 还会有很多其他 attribute,为了简单起见这里省略,下同):
&presence from=&abc@jabber.org/contact& to=&def@jabber.org/contact&&
&status&online&/status&
&/presence&
用于在两个用户之间发送消息。消息结构举例如下:
&message from=&abc@jabber.org/contact& to=&def@jabber.org/contact& type=“chat”&
&body&hello&/body&
&/message&
信息/请求,是一个请求-响应机制,管理XMPP服务器上两个用户的转换,允许他们通过相应的XML格式进行查询和响应。
&iq from=&abc@jabber.org/contact&id=“id11” type=“result”&
下一篇文章再继续学习和总结我这段时间阅读xmpp协议核心文档
RFC3920 核心协议Core 的过程中遇到的问题和自己的理解。
jessonlv——吕国栋原创文章,转载请注明出处:
作者:jessonlv 发表于 15:51:23
阅读:62 评论:0
相关 [xmpp xmpp 客户端] 推荐:
- 企业架构 - ITeye博客
最近要采用xmpp 协议搭建 web 聊天室. xmpp 是一个基于xml的协议,所用的用户验证,通讯,查询等操作传输的都是xml. ejabberd 是服务端实现 支持集群部署. 客户端实现有很多,基于java的sdk是 smack,基于js的这里采用 candy-chat (http://candy-chat.github.io/candy/).
- CSDN博客推荐文章
接着上一篇文章继续学习和总结. XMPP 系统的一个设计标准是必须支持简单的客户端. 事实上,XMPP 系统架构对客户端只有很少的几个限制. 一个XMPP 客户端必须支持的功能有:. 通过 TCP 套接字与XMPP 服务器进行通信;. 解析组织好的 XML 信息包;. 至于对客户端为何要求如此简单,概括来说就是,xmpp把相关更多功能实现都放在了服务器端去实现和处理,这样使得客户端相对解放出来.
- ITeye博客
最近在整理一些这方面的资料,闲话少说,咱还是直奔主题吧 :). 一、基于xmpp实现的openfire的配置安装. 1、 下载最新的openfire安装文件. 在这里面openfire是服务器,下面还有一个spark,这个是一个XMPP协议通信聊天的CS的IM软件,它可以通过openfire进行聊天对话.
- 康爷 - Solidot
微软在BUILD会议上宣布Windows Live Messenger将支持开放标准网络即时消息协议XMPP. Google Talk、Facebook聊天服务和IBM Lotus Sametime都等支持XMPP. 微软表示,Windows Live Messenger将提供XMPP接口,允许用户将Messenger整合到基于Web、桌面和移动IM产品中.
- CSDN博客互联网推荐文章
XMPP 是一种很类似于http协议的一种数据传输协议,它的过程就如同“解包装--〉包装”的过程,用户只需要明白它接受的类型,并理解它返回的类型,就可以很好的利用xmpp来进行数据通讯.
XMPP(可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探测.
- 移动开发 - ITeye博客
本文主旨在于,对目前Android平台上最主流的几种消息推送方案进行分析和对比,比较客观地反映出这些推送方案的优缺点,帮助大家选择最合适的实施方案. 方案1、使用GCM服务(Google Cloud Messaging). 简介:Google推出的云消息服务,即第二代的C2DM. 优点:Google提供的服务、原生、简单,无需实现和部署服务端.
- Tim[后端技术]
XMPP由于上下游良好的开源生态得到了广泛的采纳与应用,但是到了移动为主的时代,XMPP的不足也暴露出来. XMPP全称是Extensible Messaging and Presence Protocol(也称为Jabber),是一种支持消息及状态的协议,但在线状态在移动场景并是一个必需的feature.
- CSDN博客推荐文章
由于需要erlang支持,那么下载erlang-R14B04. 使用该脚本测试的时候,要禁用XMPP服务器的auth验证模块,不然账号密码不对,登陆不进去. 单个IP的端口65535的问题导致单个机器模拟的连接数有限,这个问题我没解决,只能通过使用很多机器都开这个服务来解决. 作者:smm 发表于 3:21:36
- 博客园_首页
在XMPP消息推送这个问题上,网上已经有很多资料了,本人觉得很好的一篇资料是:
/topic/1117043. 提供了一个连接下载源码:
/file/bhkfse3i#%20Androidpn.rar. 在源码的使用过程中要注意的地方有两点,网上的那篇资料好像忽略了一个重要的地方,就是要改resources文件夹下面的jdbc.properties,将里面关于数据库的配置改为自己的,另一个需要注意的地方就是改android端的ip了.
- 山石 - 博客园-首页原创精华区
基于XMPP协议的手机多方多端即时通讯方案. 基于XMPP协议的手机多方多端即时通讯方案. 3、
为什么选择XMPP协议. 5、 Xmpp提供电子名片协议. 1、
什么是Openfire. 2、
为什么使用Openfire. 3、
Windows下搭建服务器.
坚持分享优质有趣的原创文章,并保留作者信息和版权声明,任何问题请联系:@。}

我要回帖

更多关于 ios xmpp获取好友列表 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信