zoukankan      html  css  js  c++  java
  • iOS-XMPP(转)

    IM的实现原理
        在我最初学习编程的时候,曾经用JAVA实现了一个最简单版的IM通讯,即通过Socket建立两台电脑之间的连接,然后发送IO流来进行即时通讯,我们现在所使用的IM软件尽管看上去非常复杂,但是基本的原理和以上的差不多,无非是采用服务器<>客户端的架构,通过登陆到服务器来获取个人资料和好友,然后聊天时直接通过IP和好友进行即时通讯。

    XMPP协议的网络架构
        XMPP是一个典型的C/S架构,而不是像大多数即时通讯软件一样,使用P2P客户端到客户端的架构,也就是说在大多数情况下,当两个客户端进行通讯时,他们的消息都是通过服务器传递的(也有例外,例如在两个客户端传输文件时).采用这种架构,主要是为了简化客户端,将大多数工作放在服务器端进行,这样,客户端的工作就比较简单,而且,当增加功能时,多数是在服务器端进行.XMPP服务的框架结构如下图所示.XMPP中定义了三个角色,XMPP客户端,XMPP服务器、网关.通信能够在这三者的任意两个之间双向发生.服务器同时承担了客户端信息记录、连接管理和信息的路由功能.网关承担着与异构即时通信系统的互联互通,异构系统可以包括SMS(短信)、MSN、ICQ等.基本的网络形式是单客户端通过TCP/IP连接到单服务器,然后在之上传输XML,工作原理是:

    节点连接到服务器;
    服务器利用本地目录系统中的证书对其认证;
    节点指定目标地址,让服务器告知目标状态;
    服务器查找、连接并进行相互认证;
    节点之间进行交互。
        XMPP协议的传输是通过XML文件来传输的,并且不是类似于QQ的点对点通讯,而是客户端到服务器再到客户端的方式来实现,以上过程的一个简单的XMPP通讯流程可以如下:

     首先,由客户端连接到服务器,客户端通过IO流发送一段XML文件,在文件中包含了自身的用户名和密码。
     服务器端接收到客户端的XML文件,从中获取用户名和密码进行验证,如果验证成功,服务器会发送一个XML文件给客户端表明已经登录成功。
     登陆成功后,客户端可以通过发送一个获取好友名单的XML文件,服务器会将当前用户的好友以XML文件传到客户端。
     客户端选择一个好友,向其发送信息(其实是向服务器发送,服务器收到后会转发给对应的好友),好友收到。
         通过以上的流程,一此基本的通讯得以达成。

    Spark架构

        (上图为XMPP的一个实现Openfire+Smack+Spark的实现)

    XMPP协议的一些概念
         通过以上简介,我们了解了XMPP协议的基本流程,下面来了解一个XML中一些基本的概念。

    XMPP地址
        一个实体在XMPP网络结构中被称为一个节点,它有唯一的标示符jabber identifier(JID),即实体地址,用来表示一个用户,但是也可以表示其他内容,例如一个聊天室.一个有效的JID包括一系列元素:(1)域名(domain identifier);(2)节点(node identifier);(3)源(resource identifier).它的格式是node@domain/resourcenode@domain,类似电子邮件的地址格式.domain用来表示接点不同的设备或位置,这个是可选的,例如a在Server1上注册了一个用户,用户名为doom,那么a的JID就是doom@serverl,在发送消息时,指明doom@serverl就可以了,resource可以不用指定,但a在登录到这个Server时,fl的JID可能是doom@serverl、exodus(如果a用Exodus软件登录),也可能是doom@serverl/psi(如果a用psi软件登录).资源只用来识别属于用户的位置或设备等,一个用户可以同时以多种资源与同一个XMPP服务器连接。

    XMPP的XML流
        即时通讯的聊天是指上就是二进制流或者字符流。在以前这些命令要么用2进制的形式发送(比如QQ),要么用纯文本指令加空格加参数加换行苻的方式发送(比如MSN)。而XMPP传输的即时通讯指令的逻辑与以往相仿,只是协议的形式变成了XML格式的纯文本。这不但使得解析容易了,人也容易阅读了,方便了开发和查错。而XMPP的核心部分就是一个在网络上分片断发送XML的流协议。这个流协议是XMPP的即时通讯指令的传递基础,也是一个非常重要的可以被进一步利用的网络基础协议。所以可以说,XMPP用TCP传的是XML流。

       举个例子看看所谓的XML流是什么样子的?

    客户端:<?xml version='1.0'?>

       <stream:stream

           to='example.com'

           xmlns='jabber:client'

           xmlns:stream='http://etherx.jabber.org/streams'

           version='1.0'>

    服务器:<?xml version='1.0'?>

       <stream:stream

           from='example.com'

           id='someid'

           xmlns='jabber:client'

           xmlns:stream='http://etherx.jabber.org/streams'

           version='1.0'>

    ...其他通信...

    客户端:<message from='juliet@example.com'

                  to='romeo@example.net'

                  xml:lang='en'>

    客户端: <body>Art thou not Romeo, and a Montague?</body>

    客户端:</message>

    服务器:<message from='romeo@example.net'

                  to='juliet@example.com'

                  xml:lang='en'>

    服务器:<body>Neither, fair saint, if either thee dislike.</body>

    服务器:</message>

    客户端:</stream:stream>

    服务器:</stream:stream>

        以文档的观点来看,客户端或服务器发送的所有XML文本连缀在一起,从<stream>到</stream>构成了一个完整的XML文档。其中的stream标签就是所谓的XML Stream。在<stream>与</stream>中间的那些<message>...</message>这样的XML元素就是所谓的XML Stanza(XML节)。XMPP核心协议通信的基本模式就是先建立一个stream,然后协商一堆安全之类的东西,中间通信过程就是客户端发送XML Stanza,一个接一个的。服务器根据客户端发送的信息以及程序的逻辑,发送XML Stanza给客户端。但是这个过程并不是一问一答的,任何时候都有可能从一个方发信给另外一方。通信的最后阶段是</stream>关闭流,关闭TCP/IP连接。

    XML节

        XML节通过XML流来发送,XMPP定义了三种顶级XML节

    <iq />
    <message />
    <presence />

        XMPP给这三种节定义了五种通用属性

    to
    from
    id
    type
    xml:lang

        to属性指定接收节的JID。

        from属性指定发送者的JID。

        id属性是可选的。并且,在接收应用(通常是一个服务器)中是唯一的。注意:流ID可能是严格安全的,并且因此必须是即不能预测也不能重复的

        type属性指定目的或消息上下文,出席或IQ节的详细信息。iq节的type属性有:Error,Get,Result,Set; presence节的type属性有:Available,Subscribe,Subscribed,Unsubscribe,        Unsubscribed,Unavailable,Probe,Error,Invisible; message节的type属性有:Chat,Error,GroupChat,Headline,Normal

        xml:lang属性值指定任意可读XML字符数据的缺省语言

        <message />节定义了消息语义,<message />节可被看作“推”机制,一个实体推信息给其它实体,与EMAIL系统中发生的通信类似。所有消息节应该拥有‘to’属性,指定有意的消息接收者;根据接收到那样的一个节,服务器应该路由或传送它到有意的接收者。

        <presence />节定义了出席语义,<presence />节可被看作基本广播或“出版-订阅”机制,多实体收到他们已订阅(在这种情况下,网络可利用信息)实体的信息。总的来说,出版实体应该发送一个不带‘to’属性的出席节,在这种情况下,与此实体相连的服务器应该广播给所有订阅实体。然而,一个出版实体也可能发送一个带有‘to’属性的出席节,此种情况下,服务器应该路由或传送节到有意的接收者。

        <iq />节定义了请求语义,<iq />节可被看作一个请求-响应机制,与[HTTP]在某些方面相似。IQ语义让一个实体向其它实体请求或接收其它实体的响应成为可能。请求与响应的数据内容由IQ无素的直接子元素的命名空间声明定义,并且,交互由请求实体通过使用

  • 相关阅读:
    js小知识
    elasticsearch查询与sql对应关系
    svnkit 异常:Exception in thread "main" org.tmatesoft.svn.core.SVNException: svn: E200030: SQLite error
    spring中引入多个quertz 注意事项
    ajax跨域
    MetaException(message:For direct MetaStore DB connections, we don't support retries at the client level.)
    center os7 安装mysql
    Center OS 7
    解决js ajax跨越请求 Access control allow origin 异常
    gps位置坐标转百度坐标
  • 原文地址:https://www.cnblogs.com/linxiu-0925/p/5224814.html
Copyright © 2011-2022 走看看