`

[原]Android上GTalk以及Push机制的XMPP数据选择使用protobuf格式而非XML格式

阅读更多
http://code.google.com/p/protobuf/

先介绍下什么是protobuf以及有什么好处.
Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. Google uses Protocol Buffers for almost all of its internal RPC protocols and file formats.

protobuf在网络编程中的应用思考
http://blog.csdn.net/ciml/archive/2010/07/21/5753367.aspx
protobuf是google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言,其最大的特点是基于二进制,因此比传统的 XML表示高效短小得多。虽然是二进制数据格式,但并没有因此变得复杂,开发人员通过按照一定的语法定义结构化的消息格式,然后送给命令行工具,工具将自动生成相关的类,可以支持java、c++、python等语言环境。通过将这些类包含在项目中,可以很轻松的调用相关方法来完成业务消息的序列化与反序列化工作。

protobuf在google中是一个比较核心的基础库,作为分布式运算涉及到大量的不同业务消息的传递,如何高效简洁的表示、操作这些业务消息在google这样的大规模应用中是至关重要的。而protobuf这样的库正好是在效率、数据大小、易用性之间取得了很好的平衡.

Android上GTalk以及Push机制的XMPP数据选择使用protobuf格式
Android上Google Talk客户端以及C2DM等Push机制基于XMPP协议, 而XMPP协议通信的数据格式是XML. 正如上面所介绍的, protobuf比XML高效, 节约流量. 所以, 在这里, Google选择将protobuf作为数据格式.
实现起来也不是很复杂. 对于传统的使用XML作为数据格式的XMPP协议, 发送Packets的时候将对象数据serialize为相应的XML格式的数据, 接收Packets的时候将XML格式的数据parse为对象数据; 而对于GTalk使用protobuf作为数据格式的XMPP协议, 发送Packets的时候将对象数据serialize为相应的protobuf格式的数据, 接收Packets的时候将protobuf格式的数据parse为对象数据.

1. 针对不同的XML Packet类型用不同的字节值表示.

GtalkCoreMessageTypes定义了不同的XML Packet类型
HEARTBEAT_PING
public static final ProtoBufType HEARTBEAT_ACK;
public static final ProtoBufType LOGIN_REQUEST;
public static final ProtoBufType LOGIN_RESPONSE;
public static final ProtoBufType CLOSE;
public static final ProtoBufType MESSAGE_STANZA;
public static final ProtoBufType PRESENCE_STANZA;
public static final ProtoBufType IQ_STANZA;
public static final ProtoBufType DATA_MESSAGE_STANZA;
public static final ProtoBufType BATCH_PRESENCE_STANZA;
public static final ProtoBufType STREAM_ERROR_STANZA;
public static final ProtoBufType HTTP_REQUEST;
public static final ProtoBufType HTTP_RESPONSE;


ProtoBufStreamConfiguration定义了同的XML Packet类型对应的字节值
public static final byte HEARTBEAT_PING_TAG = 0;
public static final byte HEARTBEAT_ACK_TAG = 1;
public static final byte LOGIN_REQUEST_TAG = 2;
public static final byte LOGIN_RESPONSE_TAG = 3;
public static final byte CLOSE_TAG = 4;
public static final byte MESSAGE_TAG = 5;
public static final byte PRESENCE_TAG = 6;
public static final byte IQ_TAG = 7;
public static final byte DATA_MESSAGE = 8;
public static final byte BATCH_PRESENCE = 9;
public static final byte STREAM_ERROR = 10;
public static final byte HTTP_REQUEST = 11;
public static final byte HTTP_RESPONSE = 12;


2. Parse的流程
Smack中的PacketReader类是用来从XMPPConnection上读取Packets的. 它会首先判断useProtoBuf标志. 如果是true, 则使用ProtoBufStreamParser作为parser来解析数据流; 否则, 则使用XmlPullParser作为parser来解析数据流.

ProtoBufStreamParser的主要方法为:
public abstract void parse(ByteBuffer byteBuffer)
     throws ProtoBufStreamException, IOException;

ProtoBufStreamParser其实主要是分析数据流的前几个字节获得Packets的类型(message, presence等), 然后会调用ProtoBufEventHandler的handleProtoBuf()方法.
public interface ProtoBufEventHandler {
  public abstract void handleProtoBuf(ProtoBuf protoBuf, long paramLong);
}

而PacketReader实际上实现了ProtoBufEventHandler接口, 所以在PacketReader的handleProtoBuf()方法中进一步解析protobuf数据流, 根据不同的类型创建不同的Packet对象, 比如Message对象, Presence对象等.

3. Serialize的流程
Smack中的PacketWriter类是用来构建Packets然后写到XMPPConnection上的. 它会首先判断useProtoBuf标志. 如果是true, 则调用serializeAsProtoBuf()来形成数据流; 否则, 调用serializeAsXml()来形成数据流.
serializeAsProtoBuf()方法会调用toProtoBuf(),就像serializeAsXml()会调用toXML().
因此每种Packets类型都需要实现toProtoBuf()和toXML().
public abstract class Packet {
    public abstract ProtoBuf toProtoBuf();
    public abstract String toXML();
}

public class Message extends Packet {
    public ProtoBuf toProtoBuf() {
        ProtoBufType protoBufType = GtalkCoreMessageTypes.MESSAGE_STANZA;
        ProtoBuf protoBuf = new ProtoBuf(protoBufType);
        protoBuf.setString(MessageStanza.ID, getPacketID());
        protoBuf.setString(MessageStanza.TO, getTo());
        protoBuf.setString(MessageStanza.FROM, getFrom());
        protoBuf.setInt(MessageStanza.TYPE, Type.CHAT);
        protoBuf.setInt(MessageStanza.SUBJECT,  this.subject);
        protoBuf.setInt(MessageStanza.BODY,  this.body);
        ......
    }

    public String toXML() {
         StringBuffer buf = new StringBuffer();
         buf.append("<message");
         buf.append(" id=\"").append(getPacketID()).append("\"");
         buf.append(" to=\"").append(getTo()).append("\"");
         buf.append(" from=\"").append(getFrom()).append("\"");
         buf.append(" type=\"").append(Type.CHAT).append("\"");
         ......
         buf.append(">");
         buf.append("<subject>").append(this.subject).append("</subject>")
         buf.append("<body>").append(this.body).append("</body>")
         ......
         return buf.toString();
    }
}

public class Presence extends Packet {
    public ProtoBuf toProtoBuf() {
        ......
    }

    public String toXML() {
         ......
    }
}


serializeAsProtoBuf()方法首先通过调用Packets的toProtoBuf()获得protobuf后, 会再调用ProtoBufStreamSerializer的serialize()方法, 在serialize()方法中会把Packets类型对应的字节值加到protobuf前面.
public interface ProtoBufStreamSerializer {
    public void serialize(ProtoBuf protoBuf, OutputStream outputStream)
      throws ProtoBufStreamException, IOException;

    public byte[] serialize(ProtoBuf protoBuf)
      throws ProtoBufStreamException, IOException;
}



分享到:
评论
1 楼 xici_magic 2011-02-16  
这个也是跨平台?

相关推荐

    android xmpp push实现

    Android 平台上实现推送消息服务常常是一项挑战,因为系统本身并未提供一个完美无瑕的解决方案。本文主要探讨了如何在Android应用中实现XMPP(可扩展通讯和表示协议)推送,以及面对不同推送策略的优缺点。 XMPP是...

    ch25_gtalk.rar_android_ch25_gtalk_gtalk_gtalk andro

    总结,通过对“ch25_gtalk.rar”的分析,我们可以深入了解GTalk在Android平台上的实现,包括它的登录认证、消息传输、联系人管理以及事件通知机制。这对于开发者在构建自己的即时通讯应用时,无论是从技术选型、架构...

    Android基于XMPP协议的数据推送技术.pdf

    这在Android开发中通常依赖于Google Cloud Messaging(GCM)或Firebase Cloud Messaging(FCM)这样的服务,但是文档中提及的技术主要集中在XMPP协议上,因此实现推送的方式可能涉及在XMPP协议上构建消息推送机制。...

    Android中的XMPP应用

    - **熟悉XML格式**:由于XMPP是基于XML的数据交换协议,因此熟悉XML的基本语法对于理解XMPP的工作原理至关重要。 - **掌握网络编程基础**:良好的网络编程能力可以帮助开发者更好地处理网络连接、数据传输等问题。 -...

    XMPP DEMO android4.0通过

    总结起来,"XMPP DEMO android4.0通过"是一个演示如何在Android 4.0上实现XMPP即时通讯的应用示例,涉及到的主要知识点包括XMPP协议的理解、Android编程、XMPP客户端库的使用、状态管理和错误处理等。对于在Android ...

    android push开发

    接下来说说XMPP在android客户端上的应用。分两部分:服务端搭建和客户端实现。 服务端搭建: 点击bin目录下得run.bat,直接搭好服务,在浏览器上输入 http://127.0.0.1:7070 ,可以修改配置在conf/config....

    ft.zip_gloox_gtalk_visual c_xmpp

    【标题】"ft.zip_gloox_gtalk_visual c_xmpp " 涉及的主要知识点是使用Gloox库在Visual C++环境下通过XMPP协议进行文件传输,特别是针对Google Talk (gtalk)服务的实现。 **Gloox库**: Gloox是一个用C++编写的开源...

    GTalkSMS源码

    然后你就可以用你的主控端发送消息的方式控制你的手机 "&gt;GTalkSMS实现了一个xmpp机器人 只要你在自己的gtalk(xmpp)上增加这个机器人为好友 就能像聊天一样远程操作自己的android手机了 使用简单就像是在即时聊天...

    android Gtalk.apk

    Google Talk(Gtalk)是Google公司开发的即时通讯工具,Gtalk除了具备一般IM功能外,还加上了Viop功能,Gtalk界面清晰大方,可直接链接Gmail,轻松接受邮件。欢迎下载最新版google talk。

    XMPP协议学习资料

    1. 数据传输基于广泛使用的XMPP协议,与其他如QQ、MSN、GTalk等即时通讯服务兼容。 2. 提供了良好的框架支持,简化了开发者实现推送通知的复杂度。 3. 利用MINA框架有效处理高并发连接,提高了系统效率。 4. 采用TLS...

    Gtalk C# 开发

    在IT行业中,C#是一种广泛使用的编程语言,尤其在开发桌面应用、游戏、移动应用以及网络服务等领域。本文将深入探讨“Gtalk C# 开发”这一主题,以帮助你理解如何利用C#来构建一个GTalk客户端,并探索可能的高级功能...

    gtalk.apk-android

    gtalk.apk-android

    XMPP协议的IM客户端IMPanda

    XMPP(Extensible Messaging and Presence Protocol)是一种基于XML的开放标准通信协议,主要用于即时通讯(IM)和在线状态管理。IMPanda是利用XMPP协议实现的一款客户端应用,它旨在提供基本的消息发送功能,并逐渐...

    XMPP 协议讲解 openfire 结构分析以及插件开发指南

    XMPP的特色在于使用XML作为消息格式,使得信息交换不仅限于特定的软件或平台,还具有良好的扩展性。目前,许多即时通讯软件如Gtalk采用XMPP协议进行消息传递,而其他一些即时通讯软件如QQ和MSN Messenger则采用自己...

    gtalk-rpg:通过 gTalk 或其他基于 XMPP 的 IM 服务玩桌面 RPG-开源

    通过 gTalk 或其他基于 XMPP 的 IM 服务玩桌面 RPG。 ========== 通过 gTalk 或其他基于 XMPP 的 IM 服务玩桌面 RPG。 当今可用于在线角色扮演角色扮演的大多数程序都是使用私有服务器的专有应用程序。 如果服务器...

    基于xmpp协议的多端即时通讯方案

    - **Android客户端**:开发Android客户端需要熟悉Java或Kotlin语言,可以使用Android Studio集成开发环境。 - **iOS客户端**:开发iOS客户端需要熟悉Swift或Objective-C语言,可以使用Xcode集成开发环境。 - **跨...

    asp.net获取MSN、Gtalk好友列表例子

    MSN使用微软的实时通信(RTC)协议,而GTalk基于 Jabber/XMPP 协议。为了与这些服务交互,我们需要使用相应的API或库。由于这些服务的官方API可能有限或不再支持,开发者通常需要找到第三方库或者直接解析协议来实现...

    xmpp协议讲义

    - **XML格式**:所有通信数据均采用XML格式编码,易于解析和处理。 - **安全性**:支持TLS加密,确保通信过程中的数据安全。 ##### 主要组件 - **XML流**:用于客户端与服务器之间建立连接和交换数据的基本单元。 -...

    简易im gtalk聊天工具源码

    【简易IM GTalk聊天工具源码】是一款基于XMPP协议和Asmack库开发的Android即时通讯应用。这款工具能够实现在Android设备上的实时聊天功能,让用户能够方便地进行文字、图片或者其他形式的信息交流。然而,为了使这个...

    Android入门到精通源代码.

    9.1.2 使用XML存储Preferences数据 9.2 使用文件存储数据 9.2.1 访问应用中的文件数据 9.2.2 访问设备中独立的文件数据 9.3 使用SQLite数据库存储数据 9.3.1 SQLite数据库简介 9.3.2 SQLite数据库操作 9.3.3 使用...

Global site tag (gtag.js) - Google Analytics