xmpp 一个账号在多处登陆,但是只有一个xmpp web 客户端端收到消息。

关于Openfire修改后部分XMPP协议请求方式的更改说明_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
关于Openfire修改后部分XMPP协议请求方式的更改说明
上传于||文档简介
&&关​于​O​p​e​n​f​i​r​e​修​改​后​部​分​X​M​P​P​协​议​请​求​方​式​的​更​改​说​明
阅读已结束,如果下载本文需要使用2下载券
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩11页未读,继续阅读
你可能喜欢XmpPullParser   鉴于xmpp协议都是以xml格式来传输,因此源码中解析协议都是用到XmpPullParser来解析xml   XmpPullParser很简单,先简单介绍几个比较常用的方法
//定义一个事件采用回调方式,直到xml完毕
public int getEventType() throws XmlPullParserException ;
//遍历下一个事件,返回一个事件类型
public int next() throws XmlPullParserException, IOException
//得到当前tag的名字
public String getName();
//获得当前文本
public String getText();
//当前tag下的属性数量
public int getAttributeCount() ;
//获得当前指定属性位置的名称
public String getAttributeName(int index);
//获得当前指定属性位置的值
public String getAttributeValue(int index);
  为了更好的理解后面的源码,加一段代码来分析:
public PacketExtension parseExtension(XmlPullParser parser) throws Exception {
MUCUser mucUser = new MUCUser();
boolean done = false;
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals(&invite&)) {
mucUser.setInvite(parseInvite(parser));
if (parser.getName().equals(&item&)) {
mucUser.setItem(parseItem(parser));
if (parser.getName().equals(&password&)) {
mucUser.setPassword(parser.nextText());
if (parser.getName().equals(&status&)) {
mucUser.setStatus(new MUCUser.Status(parser.getAttributeValue(&&, &code&)));
if (parser.getName().equals(&decline&)) {
mucUser.setDecline(parseDecline(parser));
if (parser.getName().equals(&destroy&)) {
mucUser.setDestroy(parseDestroy(parser));
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals(&x&)) {
done = true;
return mucU
  里面的对象先不用理它,只需看他是如何分析这段xml的:   //协议解释,从发送一段协议给这个用户,邀请用户进入房间,理由hi join us。
&message id=&WEzG6-11& to=&/Smack& from=&/Smack& type=&get&&
&x xmlns=&http://jabber.org/protocol/muc#user&&
&invite to=&&&
&reason&hi join us&/reason&
&/message&
  parser.next();
获得第一个事件,判断是否开始标签(XmlPullParser.START_TAG) 然后再里面判断每个标签的名字 处理完后判断结尾标签(XmlPullParser.END_TAG)是否需要结束本次循环。
  //取xmlpullparse对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();   XmlPullParser parser = factory.newPullParser(); 
  //设置关联数据源   parser.setInput(reader);
接收消息以及如何解析消息
在android里面用的smack包其实叫做asmack,该包提供了两种不同的连接方式:socket和httpclient。 该包并且提供了很多操作xmpp协议的API,也方便各种不同自定义协议的扩展。 我们不需要自己重新去定义一套接收机制来扩展新的协议,只需继承然后在类里处理自己的协议就可以了。
使用socket连接服务器 将XmlPullParser的数据源关联到socket的InputStream 启动线程不断循环处理消息 将接收到的消息解析xml处理封装好成一个Packet包 将包广播给所有注册事件监听的类
逐步击破   先理解一下smack的使用,看下smack类图   下图只显示解释所要用到的类和方法,减缩了一些跟本文主题无关的代码,只留一条贯穿着从建立连接到接收消息的线。      1.解析这块东西打算从最初的调用开始作为入口,抽丝剥茧,逐步揭开。
PacketListener packetListener = new PacketListener() {
public void processPacket(Packet packet) {
System.out.println(&Activity----processPacket& + packet.toXML());
PacketFilter packetFilter = new PacketFilter() {
public boolean accept(Packet packet) {
System.out.println(&Activity----accept& + packet.toXML());
return true;
  解释:创建包的监听以及包的过滤,当有消息到时就会广播到所有注册的监听,当然前提是要通过packetFilter的过滤。   2.在这构造函数里面主要配置ip地址和端口
super(new ConnectionConfiguration(&169.254.141.109&, 9991));
View Code   3.注册监听,开始初始化连接。
connection.addPacketListener(packetListener, packetFilter);
connection.connect();
  4.通过之前设置的ip和端口,建立socket对象
public void connect() {
// Stablishes the connection, readers and writers
connectUsingConfiguration(config);
private void connectUsingConfiguration(ConnectionConfiguration config) {
String host = config.getHost();
int port = config.getPort();
this.socket = new Socket(host, port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
initConnection();
View Code   5.建立reader和writer的对象关联到socket的InputStream
private void initReaderAndWriter() {
reader = new BufferedReader(new InputStreamReader(socket
.getInputStream(), &UTF-8&));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
initDebugger();
View Code   6.实例化ConsoleDebugger,该类主要是打印出接收到的消息,给reader设置了一个消息的监听
protected void initDebugger() {
Class&?& debuggerClass = null;
debuggerClass = Class.forName(&com.simualteSmack.ConsoleDebugger&);
Constructor&?& constructor = debuggerClass.getConstructor(
Connection.class, Writer.class, Reader.class);
debugger = (SmackDebugger) constructor.newInstance(this, writer,
reader = debugger.getReader();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (Exception e) {
throw new IllegalArgumentException(
&Can't initialize the configured debugger!&, e);
View Code   7.接着建立PacketReader对象,并启动。PacketReader主要负责消息的处理和通知
private void initConnection() {
// Set the reader and writer instance variables
initReaderAndWriter();
packetReader = new PacketReader(this);
addPacketListener(debugger.getReaderListener(), null);
// Start the packet reader. The startup() method will block until we
// get an opening stream packet back from server.
packetReader.startup();
View Code   看看PacketReader类
public class PacketReader {
private ExecutorService listenerE
private boolean
private XMPPC
private XmlPullP
private Thread readerT
protected PacketReader(final XMPPConnection connection) {
this.connection =
this.init();
* Initializes the reader in order to be used. The reader is initialized
* during the first connection and when reconnecting due to an abruptly
* disconnection.
protected void init() {
done = false;
readerThread = new Thread() {
public void run() {
parsePackets(this);
readerThread.setName(&Smack Packet Reader &);
readerThread.setDaemon(true);
// create an executor to deliver incoming packets to listeners.
// we will use a single thread with an unbounded queue.
listenerExecutor = Executors
.newSingleThreadExecutor(new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread thread = new Thread(r,
&smack listener processor&);
thread.setDaemon(true);
resetParser();
* Starts the packet reader thread and returns once a connection to the
* server has been established. A connection will be attempted for a maximum
* of five seconds. An XMPPException will be thrown if the connection fails.
public void startup() {
readerThread.start();
* Shuts the packet reader down.
public void shutdown() {
done = true;
// Shut down the listener executor.
listenerExecutor.shutdown();
private void resetParser() {
parser = XmlPullParserFactory.newInstance().newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(connection.reader);
} catch (XmlPullParserException xppe) {
xppe.printStackTrace();
* Parse top-level packets in order to process them further.
* @param thread
the thread that is being used by the reader to parse incoming
private void parsePackets(Thread thread) {
int eventType = parser.getEventType();
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals(&message&)) {
processPacket(PacketParserUtils.parseMessage(parser));
System.out.println(&START_TAG&);
} else if (eventType == XmlPullParser.END_TAG) {
System.out.println(&END_TAG&);
eventType = parser.next();
} while (!done && eventType != XmlPullParser.END_DOCUMENT
&& thread == readerThread);
} catch (Exception e) {
e.printStackTrace();
if (!done) {
private void processPacket(Packet packet) {
if (packet == null) {
// Loop through all collectors and notify the appropriate ones.
for (PacketCollector collector : connection.getPacketCollectors()) {
collector.processPacket(packet);
// Deliver the incoming packet to listeners.
listenerExecutor.submit(new ListenerNotification(packet));
* A runnable to notify all listeners of a packet.
private class ListenerNotification implements Runnable {
public ListenerNotification(Packet packet) {
this.packet =
public void run() {
for (ListenerWrapper listenerWrapper : connection.recvListeners
.values()) {
listenerWrapper.notifyListener(packet);
创建该类时就初始化线程和ExecutorService
接着调用resetParser() 方法为parser设置输入源(这里是重点,parser的数据都是通过这里获取) 调用startup启动线程,循环监听parser 如果接收到消息根据消息协议的不同将调用PacketParserUtils类里的不同方法,这里调用parseMessage()该方法主要处理message的消息,在该方法里分析message消息并返回packet包。 返回的包将调用processPacket方法,先通知所有注册了PacketCollector的监听,接着消息(listenerExecutor.submit(new ListenerNotification(packet)); )传递给所有注册了PacketListener的监听。 这样在activity开始之前注册的那个监听事件就会触发,从而完成了整个流程。
辅助包   比如PacketCollector 这个类,它的用处主要用来处理一些需要在发送后需要等待一个答复这样的请求。
protected synchronized void processPacket(Packet packet) {
System.out.println(&PacketCollector---processPacket&);
if (packet == null) {
if (packetFilter == null || packetFilter.accept(packet)) {
while (!resultQueue.offer(packet)) {
resultQueue.poll();
View Code   该方法就是将获取到的包,先过滤然后放到队列里,最后通过nextResult来获取包,这样就完成一个请求收一个答复。
public Packet nextResult(long timeout) {
long endTime = System.currentTimeMillis() +
System.out.println(&nextResult&);
return resultQueue.poll(timeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) { /* ignore */
} while (System.currentTimeMillis() & endTime);
return null;
  这样整个流程就完成了,最后总结一下,如图     
参考文章   /not-code/archive//2124340.html
与本文相关的文章IOS即时通信__十句代码完成登陆发消息功能__强大的SDK,XMPP里面的代码再也不用去写了。。。
[问题点数:100分]
IOS即时通信__十句代码完成登陆发消息功能__强大的SDK,XMPP里面的代码再也不用去写了。。。
[问题点数:100分]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。XMPP 协议适合用来做移动 IM 么 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
XMPP 协议适合用来做移动 IM 么
10:26:06 +08:00 · 10109 次点击
XMPP 协议是什么
XMPP(Extensible Messaging and Presence Protocol,前称Jabber)是一种以 XML 为基础的开放式实时通信协议,关于它的协议细节,网上已经有太多分析文章,我这里就不再赘述(而且,我也不可能比别人解释的更清楚)。简单来看这个协议,我们只需要知道:
1,XMPP 的三种基本角色:客户端、服务器和网关,通信能够在这三者的任意两个之间双向发生。服务器端同时承担了客户端信息记录、连接管理和信息路由的功能。网关则承担着与异构系统的互联互通功能。在 RFC
3920 XMPP Core 中对 XMPP 网络结构有一个描述:
C1&-S1&S2—C3
C2&-+&G1===FN1===FC1
这里 C1,C2,C3 表示 XMPP 客户端;S1,S2 表示 XMPP 服务器;G1 表示网关,用来负责 XMPP 协议和外部聊天协议的转换;FN1 表示外部消息网络的服务器,FC1 表示外部网络客户端。
大家可能会奇怪,这里为什么需要一个网关呢。这要从 XMPP 的来源说起。1996 年 Mirabilis 公司推出了世界上第一个即时通信系统 ICQ,不到 10 年,IM 就成了最流行的应用之一,MSN、Gtalk、雅虎即时通、AIM、Adium、Pidgin 等各种软件如雨后春笋般涌现,但是这些服务之间没有统一的标准,不能互联互通,XMPP 的设计目的就是为了实现整个及时通信服务协议的互通,让 IM 成为继 WEB 和 Email 之后的互联网第三大服务。
2,XMPP 的消息格式。
XMPP 协议的所有消息都是 XML 格式的,这是 XMPP 协议的另一个充满历史意味的选择,想当年 SOA / SOAP 一时间爆发起来,很多消息交换协议都采用了 XML 格式,但是不想 XML 很快就成了「大数据」的代名词。在 RFC
3920 XMPP Core 中定义了两个基础概念,XML Stream 和 XML Stanza,XML Stream 是两个节点之间进行数据交换的容器,它定义了顶层的XML节点 &stream&;XML Stanza 则定义了实体消息的具体语义单元,在 XMPP 中定义了 3 个顶层消息:
2.1 Presence
用于确定用户的状态。消息结构举例如下(每个 XML 的 node 还会有很多其他 attribute,为了简单起见这里省略,下同):
&presence from=&abc@jabber.org/contact& to=&def@jabber.org/contact&&
&status&online&/status&
&/presence&
2.2 Message
用于在两个用户之间发送消息。消息结构举例如下:
&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”&
3,XMPP 的交互流程。
XMPP 通过 TCP 传输了什么内容?在 QQ 里面,消息是使用二进制形式发送的,在 MSN 里面是采用纯文本指令加参数加换行符的形式发送的,而 XMPP 传输的即时通讯指令与他们相仿,只是协议的形式变成了 XML 格式的纯文本,这让解析更容易,方便了开发和查错,但是也带来了数据负载过重的缺点,而被人广为诟病。
XMPP 聊天的过程如下:
所有从一个 client 到另一个 client 的消息和数据都要经过 XMPP Server;
client1 连接到Server;
server 利用本地目录系统的证书对其认证;
client1 指定 client2 目标地址,让 server 告知 client2 目标状态;
server 查找,连接并进行互相认证;
client1 和 client2 进行交互。
XMPP 系统实测
XMPP 协议的最主要的一点就是开放,不管是协议、客户端,还是 Server 端,都有成熟的实现方案。为了实际感受 XMPP 协议的聊天过程,我使用 asmack library + OpenFire 服务器搭建了一套完整的测试环境。
OpenFire 采用 Java 开发,是一个基于 XMPP 协议 的开源的实时协作服务器,它的安装和使用都非常简单,自带有一个内置的存储数据库(当然,你也可以使用独立数据库如Mysql等),并利用 Web 进行管理。其他类似的开源系统还有很多,eJabber、Tigase 也经常被用到。但是根据我们之前的经验,这些开源系统能支持的并发连接数都不高,要是有超过10万的用户同时连上来,对它们来说就快达到单机的瓶颈了,这时候一般都需要水平拆分,但是拆分之后服务器之间的 session 同步负担会大幅加重,对于性能又带来不小的抵消。所以这些系统大都被拿来做研究和测试用,很少见到大规模在生产环境中使用的。
好吧,我们还是来实际聊聊看。为了体现真实性,选取了程序员圈子里面较大概率可能发生的几段典型对话:
Case1-搭讪
猿:你吃饭了吗?
猿:你在干什么呢?
猿:你那天气好吗?
MM:还可以
猿:你最近忙吗?
猿:。。。。
猿:哦,这样啊,我就想知道你在干什么,那你继续忙吧,拜拜
Case2-请教
A:嘿 //是什么意思啊?
A:呃 我问你//是什么意思?
A:我刚才不是问了么?
A:你再看看记录&
B:看完了.
A:&&所以//是啥?
B:所以什么?
A:你存心耍我呢吧?
B:没有啊 你想问什么?
Case3-约会
女:你能让这个论坛的人都吵起来,我今晚就跟你走.
某猿:PHP是最好的语言!
论坛一下炸翻了天,女:i服了u,我们走吧,你想干啥都行.
某猿:今天不行,我一定要说服他们,PHP必须是最好的语言
Case4-借钱
A:哥们儿,有钱吗?
A:借我点呗?
B:啊?你说什么?
A:借我点呗?
B:不是,上一句?
A:有钱吗?
A:晕,程序重新请求一下,结果还不一样了!
实际结果如下,我在 Nexus5 上面运行一个 IM app,连接上我自己搭建的 openfire 服务器,然后模拟了上面几段对话,在几个参与者的前提下,消息实时性还挺好,但在系统设置-》网络流量中看到,整个聊天过程中该 app 消耗掉的网络流量高达 36KB,聊天记录的文本文件大小为 8KB,也就是说网络流量的 70% 都消耗在 XMPP 协议层了,这个数字正好吻合了维基百科上吐槽的数据冗余率。
最后测试下来看,我个人感觉是,对于移动互联网来说,省电、省流量是所有底层服务的一个关键技术指标,XMPP协议看起来已经落后移动互联网了。
41 回复 &| &直到
00:01:35 +08:00
& & 10:40:32 +08:00
嗯,个人觉得XMPP不适合,我们在开发SLIMPP,GitHub项目:
& & 10:57:36 +08:00
@ 你这个基于 MQTT 的好像不错, 可以问问现在是开发到什么状态了吗?, 留意下;
& & 11:12:02 +08:00
关注,现在要做一个。
& & 11:16:03 +08:00
注册了下,貌似还不能用
& & 11:19:44 +08:00
@ 基础协议刚开发完,比如iOS的CocoaMQTT, erlang的mqtt server。现在开发Android的一个Demo,0.1版本应该在10月发布,然后迭代协议到1.0
& & 11:22:16 +08:00
XMPP用的XML,overhead太大了,大部分情况下结构描述比信息本身都大,非常不适合在流量有限的移动环境中使用。
& & 11:28:52 +08:00
@ 嗯,那个是协议开放站点,还只有web部分,手机端刚开始不久
& & 11:40:47 +08:00
XMPP 协议确实非常蛋疼,但是好处是足够完善,实现也很多,适合快速开发
& & 11:47:18 +08:00
SIP 也一样,开销非常大。
但我还是很推崇 XMPP,优势在协议完备性、各种实现的成熟度等等方面。
可以考虑在实现层面做一下改造,将 XMPP 报文在底层 TCP 传输时做一次编解码,转换成自定义的二进制格式,只需要改造一下 smack 库和 openfire 源码部分,对于上层应用开发来说完全透明,原来 smack 怎么用还是怎么用。
底层编码后的冗余数据大大减少,节省流量和功耗。
另外,考虑 XMPP 各种协议扩展较多,我们只需要针对最常用、最频繁的 XMPP 报文做编解码即可,其他不常用的仍然维持现有文本格式,对流量的贡献可控。
& & 11:49:45 +08:00
XMPP非常烂。离开了libjingle2的XMPP在桌面上都是一坨废物。
& & 11:52:54 +08:00
丰总,你还在写代码吗丰总
& & 13:00:54 +08:00
MQTT 值得你拥有!
& & 14:30:56 +08:00
@ 哈哈,写啊,我们公司工程师都写代码的。
& & 14:31:46 +08:00
推荐大家考察一下我们推出的聊天服务:
& & 14:43:29 +08:00
哈哈,话说听了上期的teahour,说到AVOS就你一个在做IM,是这样吗?
@
& & 14:58:35 +08:00
@ 不是不是,我们有一个「小团队」在做 IM,主要负责的工程师是
& & 15:04:44 +08:00
@ 这样啊,那顺便了解一下你们的IM用C/C++、Golang或者其他?这方面我也是比较感兴趣的,所以想特别了解一下。
& & 16:04:49 +08:00
xml上面zip一下应该会有改善吧
& & 16:08:23 +08:00
@ 我们服务器端是用 Clojure 写的,整个 AVOS Cloud() 的后端和网站,都是 Clojure 写出来的:)
& & 16:47:27 +08:00
@ 对的,只是没想到IM也用Clojure, 感谢分享。
& & 17:00:03 +08:00
关注,我们暂时用socket.io实现,也在寻找比较靠谱的协议
& & 17:15:15 +08:00
不适合,首先传输用的是XML,构造和解析复杂,传输冗余大。
另外,它对不稳定的移动网络不友好,经常会发生丢消息的情况。
我认为成熟的移动IM,(或者根本不应该叫IM,移动网络的特点本身就决定了它不适合做即时通讯)应该同时兼容socket和HTTP,网络好的时候用socket保证实时性,网络差的时候用HTTP保证可靠性。
还有一个血的教训是,不要让它负责除了聊天之外的其他任何事情,好友关系处理、用户资料设置什么的,最好都自己另外弄一套。XMPP自带的扩展和传输都很麻烦
& & 18:44:31 +08:00 via iPhone
作为一个趟过该浑水的人,我觉得自己搞私有协议远比xmpp好,因为用了之后你会发现里面的很多本来是好的东西,最后却变成了负担!特别对于移动网络
& & 19:08:48 +08:00
@ 非常有道理,我们直接JSON/HTTP+MQTT混合,网络好用MQTT推送,网络差通过HTTP同步。协议层面尽量支持Sync Pull和PUSH混合。
& & 19:29:43 +08:00
& & 19:52:25 +08:00
& & 20:03:15 +08:00
可以看看我们的服务,基于mqtt的
& & 20:48:41 +08:00
XMPP太重,如果需求不复杂,socket.io自己定义下协议就够用了。
& & 21:12:45 +08:00
@ 嗯,AVOS Cloud的聊天服务就是自定义协议,并且也支持socket.io,最后我们的体会是根本不需要那些「开放」且「重量级」的协议!
& & 09:00:48 +08:00
有没有支持视频聊天的协议?除了xmpp扩展以外?
& & 12:56:25 +08:00
文本沟通的话IRC协议就够了,只是IRC更面向群聊。
& & 14:01:11 +08:00
不适合。协议设计比较臃肿,XMPP协议最初设计时也没考虑移动端。
&message&本身是可丢弃的,掉了也就掉了。使用XMPP一般考虑的是服务端客户端有开源实现可抄,二来就是开放性了。
就现有开源实现来说,Erlang的那个ejabberd实现不太清楚,其它openFire, jabberd2感觉上量都有问题。群消息更是大深坑。
文件传输与音视频这块,其实XMPP也就负责握个手,该怎么走RTCP,到时还得怎么走。
量少浅尝可以,量大最终会开始动手改造。
倒是阅读XMPP协议蛮有趣的,没想到里面有这么多纯搞笑协议的RFC。比如XMPP-二进制版。
& & 17:18:58 +08:00
@ +1 openfire/ejabberd能支持的并发连接都比较有限
& & 17:45:08 +08:00
大家应该看下xmpp产生的历史。当时它的目标是提供一种通用的协议来试不同厂商的im可以互相通信。
它的性能并不好,而且因为是xml协议并不适用目前国内还对流量敏感的用户,并发量也上不去
& & 17:50:45 +08:00
& & 18:42:36 +08:00
坐等IM开源……
& & 01:56:13 +08:00
& 整个聊天过程中该 app 消耗掉的网络流量高达 36KB,聊天记录的文本文件大小为 8KB,也就是说网络流量的 70% 都消耗在 XMPP 协议层了,这个数字正好吻合了维基百科上吐槽的数据冗余率。
首先,其实浪费的带宽并没有你想象那么高比例。因为你没有考虑IP层和TCP层的带宽占用。我估计这种短小聊天信息如果有8KB,那么TCP/IP包头加起来恐怕也有10KB到20KB了。那么算上这些带宽占用,XMPP协议层占用的带宽也就在50%左右了。
其次,XMPP基于XML协议层格式繁琐,但信息量并不高,所以如果要压缩,那么压缩率就会很高。XMPP协议通常要通过TLS加密,可以启用TLS压缩选项。
最后,无论使用任何协议,文本聊天都不会占用很多带宽,稍微浪费一点,问题不大。
& & 11:24:47 +08:00
不适合。虽然说XMPP本身是一个非常完整的协议,而且扩展性相当好,也有一些很好的Broker。但它并不适合用来做移动IM。其中一个劣势@ 已经提到,就是它本身协议承载数据比例太低,差不多70%的流量都是消耗在标签上。另一个麻烦的问题就是它的延迟大。我们试验过用XMPP来做一个简单的Connect和用户认正,不仅要用1K的流量,还需要5-7次的交互,换句话说,一个登录就是秒级的延迟(移动互联网一个环回大概就是400、500毫秒)。另一个缺点就是XMPP的编解码也是很重,因为它是纯文本的解析器,你要用纯文本去做,不管是编码还是解码都是比较重的,在移动环境下合适。
推荐用MQTT协议,它是二进制协议,而且本身非常精简,做移动网络环境下做IM非常合适,省电省流量。它的做法是一个订阅/发布系统,拿到权限的人就可以往频道里发消息,任何在这个频道里的人就可以收到。MQTT还是开放协议,有很多开源实现,可以用它的开源实现搭个环境来玩一玩。另外很重要的一点就是它的扩展很方便,它原来就留了两个两个命令字,再加上它协议头本身很轻,在它的扩展命令字上做一些简单的事情就可以扩展出很多命令字。
我们云巴yunba.io是基于MQTT协议做双向消息实时推送,也支持Socket.io。开发者可以使用云巴,快速搭建包括移动IM以内的各类型实时应用。可以稳定支持千万级亿级海量用户。我们设立多处主干机房,全国范围内消息延迟在0.2s以内。
我们也投入了大量时间精力研究实践实时海量数据通讯、统计、存储等问题。之前创始人还在ArchSummit上就这方面做了的分享,题目就是实时系统架构和实践,有兴趣的可以戳http://t.cn/RhUxmwN看视频,全程干货,当时也提到了协议选择的问题。
对了,还有一个基于云巴产品开发的移动IM开源Demo,或许有用哈,Github地址http://t.cn/RPxwZjQ
& & 09:08:28 +08:00
之前用过一阵子XMPP,感觉除了大家提到的XML冗余之外,还有一些限制它适用性的地方。
最主要就是它有一下自己的业务设计,比如加入room需要客户端发送presence,需要先主动获取 roster 才能获取好友状态的更新。叫
一般来讲采用 XMPP 主要的好处就是可以直接使用很多开源的产品。但是因为本身也算比较复杂,这些产品上做一些自己的定制就没那么容易。
在移动端我不熟悉,我觉得如果使用第三方的平台实现实时通信可能是比较快速的选择。
ps ejabberd 是比较有名的 erlang 实现,实现的xmpp协议比较全,而且性能貌似是目前最好的吧? 不如 openFire 吗?
& &305 天前
好老的文了。很不错,顶一下。
& &216 天前
@ 可是是 openfire 等服务端有现成的消息系统,自己通过其他协议实现还要很多工作要做,小项目做这么多不现实。
& · & 280 人在线 & 最高记录 1893 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.7.3 · 67ms · UTC 19:46 · PVG 03:46 · LAX 12:46 · JFK 15:46? Do have faith in what you're doing.}

我要回帖

更多关于 xmpp js客户端 的文章

更多推荐

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

点击添加站长微信