full text https://www.ibm.com/developerworks/cn/xml/tutorials/x-realtimeXMPPtut/

联机状态

联机状态信息包含在一个联机状态(presence)节中。如果 type 属性省略,那么 XMPP 客户端应用程序假定用户在线且可用。否则,type 可设置为 unavailable,或者特定于 pubsub 的值:subscribesubscribedunsubscribe 和 unsubscribed。它也可以是针对另一个用户的联机状态信息的一个错误或探针。

一个联机状态节可以包含以下子元素:

  • show:一个机器可读的值,表示要显示的在线状态的总体类别。这可以是 away(暂时离开)、chat(可用且有兴趣交流)、dnd(请勿打扰)、或 xa(长时间离开)。
  • status:一个可读的 show 值。该值为用户可定义的字符串。
  • priority:一个位于 -128 到 127 之间的值,定义消息路由到用户的优先顺序。如果值为负数,用户的消息将被扣留。

例如,清单 6 中的 boreduser@somewhere 可以用这个节来表明聊天意愿:

清单 6. 样例联机状态通知
<presence xml:lang="en"><show>chat</show><status>Bored out of my mind</status><priority>1</priority>
</presence>

注意 from 属性此处省略。

另一个用户 friendlyuser@somewhereelse 可以通过发送 清单 7 中的节来探测 boreduser@somewhere 的状态:

清单 7. 探测用户状态
<presence type="probe" from="friendlyuser@somewhereelse" to="boreduser@somewhere"/>
Boreduser@somewhere's server would then respond with a tailored presence response:
<presence xml:lang="en" from="boreduser@somewhere" to="friendlyuser@somewhereelse"><show>chat</show><status>Bored out of my mind</status><priority>1</priority>
</presence>

这些联机状态值源自 “个人-个人” 消息传递软件。show 元素的值 — 通常用于确定将向其他用户显示的状态图标 — 在聊天应用程序之外如何使用现在还不清楚。状态值可能会在微博工具中找到用武之地;例如,Google Talk(一个 XMPP 聊天服务)中的用户状态字段的更改可以被导入为 Google Buzz 中的微博条目。

另一种可能性就是将状态值用作每用户应用程序状态数据的携带者。尽管此规范将状态定义为可读,但没有什么能够阻止您在那里存储任意字符串来满足您的要求。对于某些应用程序而言,它可以不是可读的,或者,它可以携带微格式形态的数据负载。

您可以为一个 XMPP 实体拥有的每个资源独立设置联机状态信息,以便访问和接收连接到一个应用程序中的单个用户的所有工具和上下文的数据只需一个用户帐户。每个资源都可以被分配一个独立的优先级;XMPP 服务器将首先尝试将消息传递给优先级较高的资源。

XMPP 使用 BOSH 越过 HTTP

要通过使用 JavaScript 的 XMPP 进行通信的 web 应用程序必须符合一些特殊要求。出于安全考虑,不允许 JavaScript 从 web 页面的域与不同域上的多个服务器通信。如果您的 web 应用程序界面被托管在 application.mydomain.com,所有 XMPP 通信也必须发生在application.mydomain.com

防火墙是另一个问题所在。理想情况下,如果您将 XMPP 用作您的 web 界面的实时元素的基础,那么您希望它对防火墙后面的用户有效。但是,公司防火墙通常只对少数几个协议开放几个端口,以便允许 web 数据、电子邮件和类似的通信通过。默认情况下,XMPP 使用端口 5222,这很可能是公司防火墙阻止的端口。

假设您知道您的用户前面的防火墙在端口 80 上允许 HTTP(这是用于访问 web 的默认协议和端口)。理想情况是您的 XMPP 通信能够越过该端口上的 HTTP。但是,HTTP 的设计并不针对持续连接。web 的架构不同于实时数据所需的通信架构。

下面我们看看 Bidirectional-streams Over Synchronous HTTP (BOSH) 的标准,该标准为双向同步数据提供一个模拟层。借助这个标准,可以与一个 XMPP 服务器建立一个较长的 HTTP 连接(时长一分钟或两分钟)。如果新数据在那个期间到达,则 HTTP 请求返回数据并关闭;否则,该请求只是失效。不管是哪种情况,一旦一个请求关闭,另一个请求将重新建立。尽管结果是对一个 web 服务器的一系列重复连接,但它是一个比 Ajax 轮询更有效的数量级,特别是因为连接到的是一个专业服务器而不是直接连接到 web 应用程序。

BOSH 上的 XMPP 允许 web 应用程序通过一个原生连接持续与 XMPP 服务器通信。客户端通过端口 80 上的 HTTP 上的一个标准 URL 连接。然后,web 服务器将这个连接代理到由 XMPP 服务器操作的一个不同端口 — 通常是 7070 — 上的 HTTP URL。这样,无论何时数据被发送到 XMPP 服务器,web 应用程序只需使用一些资源,而 web 客户端可以使用通常支持的 web 标准从防火墙后操作。维持 BOSH 的较长 HTTP 轮询的开销主要由 XMPP 服务器而不是 web 服务器或 web 应用程序承担。web 服务器和 XMPP 服务器都不会受到与使用 JavaScript 进行通信一样的域限制,正是因为这一点,消息才能够被发送到其他 XMPP 服务器和客户端。

现在,您理解了 XMPP 如何适合实时 web,可以下载并设置它,以便开始创建这个 Pingstream 应用程序。

回页首

获取和安装一个 XMPP 服务器

在本小节中,您将安装 Openfire XMPP 服务器并配置它来支持您的实时 web 应用程序。

选择一个 XMPP 服务器

有两个领先的开源 XMPP 服务器可以免费下载。它们都应用广泛并通过 GNU Public License version 2 许可,每个服务器都有自己的优势和缺点:

  • ejabberd:ejabberd 中的 e 指的是 Erlang,一种软实时编程语言。这一技术基石使 ejabberd 非常快。它还与 XMPP 核心和相关标准高度兼容。ejabberd 可以安装在大多数环境中。
  • Openfire:Openfire 用 Java™ 语言编写,用户友好,安装方便。

配置 Apache 以通过 BOSH 转发 XMPP

Openfire 在 http://localhost:7070/http-bind 维护了一个 HTTP 绑定 URL,以便通过 BOSH 访问。要在端口 80 上使用这个 URL,您必须配置 Apache HTTP Server 以将一个 URL 转发到这个位置。为此,您需要启动代理模块。

打开您的 http.conf Apache 配置文件并找到 mod_proxy.so 和 mod_proxy_http.so 的 LoadModule 条目,它们默认被注释掉。移除前导的井字符(#),取消注释。这个配置文件的 Dynamic Shared Object (DSO) Support 部分中的多个适当的行(不一定在一起)现在应该类似于 清单 8:

清单 8. 启用 Apache HTTP Server 中的代理支持
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_module modules/mod_proxy.so

在配置文件的末尾,添加 清单 9 中的行(如果您没有将 locahost 作为您的测试服务器环境,则应将 127.0.0.1 替换为您的服务器 IP 地址):

清单 9. httpd.cof 中的 XMPP 代理规则
# XMPP proxy rule
ProxyRequests Off
ProxyPass /xmpp-httpbind http://127.0.0.1:7070/http-bind/
ProxyPassReverse /xmpp-httpbind http://127.0.0.1:7070/http-bind/

注意,在 清单 9 中,您在端口 80 上使用了一个稍微不同的 URL:/xmpp-httpbind。这个 URL 是 strophe.js(您稍后将用到的客户端 JavaScript 框架)分配给一个用于设置 BOSH 端点的变量的值。

重启服务器。现在,您可以开始编写使用 XMPP 的 web 应用程序了。

浏览器应用程序:Strophe.js 和 jQuery

在本小节中,您将编写一些 JavaScript 函数,以便通过 BOSH 上的 XMPP 接收消息,并构建一个 HTML 用户界面来显示接收到的通知。

创建用户界面

现在您需要创建用户界面来接收通知。Strophe.js 是用于通过 BOSH 发送和接收 XMPP 数据的常用 JavaScript 库。对于 Pingstream 中的目的,您只需接收数据,尽管有一点是显而易见的:双向通信允许您快速构建丰富的协作环境。

尽管有几个版本,但 Strophe 的 JavaScript 版本作为一个基于浏览器的 XMPP 客户端对您而言是最有用的。下载压缩包(参见 参考资料)并将其解压缩到 pingstream 的 strophejs 文件夹中。

jQuery JavaScript 框架极大地简化了事件处理和 DOM 操作。本文提供的 Strophe.js 示例广泛使用该框架,这两者简直是 “天生一对”。下载 jQuery(参见 参考资料 中的链接)并将这个缩微版放到 pingstream 中的 jquery 文件夹中。

新建一个 index.html 文件。在该文件中包含对刚才下载的 Strophe 和 jQuery 库的引用,以及对稍后即将定义的 pingstream.js 库的引用。在body 元素中,添加一个 ID 为 notifications 的 div 元素,如 清单 23 所示:

清单 23. 客户端 HTML 页面
<!DOCTYPE html>
<html><head><title>Latest content</title><script type="text/javascript"
src="jquery/jquery-1.4.2.min.js"></script><script type="text/javascript"
src="strophejs/strophe.js"></script><script type="text/javascript"
src="pingstream.js"></script></head><body><h1>Latest content:</h1><div id="notifications"></div></body>
</html>

创建 JavaScript 文件 — pingstream.js — 您刚才在 清单 23 中引用的。在 pingstream.js 的顶端,定义此前在 Apache 中配置的 BOSH 代理端点,如 清单 24 所示:

清单 24. 设置 BOSH 端点
var BOSH_SERVICE = '/xmpp-httpbind';
var connection = null;

当页面完全加载后,您想自动连接到 XMPP 服务器。您可以使用 jQuery 的 $(document).ready 调用实现这个目标;其中,您新建一个strophe.js Strophe.Connection 对象并用它连接到服务器,如 清单 25 所示:

清单 25. 建立一个通过 BOSH 的连接
$(document).ready(function () {connection = new Strophe.Connection(BOSH_SERVICE);connection.connect(    "sendinguser@127.0.0.1","sendingpass",onConnect);});

更健壮的选项

对于本教程的目的,您正在使用此前定义的发送方。对于一个更健壮的应用程序,更好的方法可能是为每个注册应用程序用户创建一个新用户,并将每个用户订阅到一个 “发布-订阅” 界面。或者,如果您将用户名和密码留空并将 XMPP 服务器配置为接受这种类型的连接,那么 Strophe.js 可以匿名登录。在这些情况下,将针对每个匿名用户动态创建一个 JID;这些 JID 必须受到管理。最后,您还可以扩展 XMPP 聊天室。

在 清单 25 中,Strophe.Connection.connect 方法包含一个对 onConnect 函数的引用,作为它的一个参数。onConnect 将在连接建立后立即启动。您可以利用这个机会来为入向消息添加一个通知处理程序;您在这里注册了一个名为 notifyUser 函数。随后,您发送了一个简单的联机状态节。

要确保您可以连接并接收新消息,您还需向用户发送一个友好通知。

将 清单 26 中的代码添加到您的 JavaScript 文件中的 $(document)ready 调用上方:

清单 26. 处理入向 XMPP 消息
function onConnect(status)
{$('#notifications').html('<p class="welcome">Hello!
Any new posts will appear below.</p>');connection.addHandler(notifyUser, null, 'message', null, null,  null);connection.send($pres().tree());
}

最后,由于您注册了通知处理程序,因此,只要 XMPP 客户端接收到消息节,Strophe.js 就会调用 notifyUser(msg) 函数。msg 参数是 XML 节本身的一个表示,可以如 清单 27 所示查询:

清单 27. 查询 msg 参数
var elems = msg.getElementsByTagName('body');
var body = elems[0];
$('#notifications').append(Strophe.getText(body));

理想情况下,您希望对消息进行限制,以便只显示您的服务器端发送用户发送的消息。您可以将它封装到构成 notifyUser 函数主体的一个 if语句中,如 清单 28 所示:

清单 28. notifyUser 函数
function notifyUser(msg)
{if (msg.getAttribute('from') == "testuser@127.0.0.1/pingstream") {var elems = msg.getElementsByTagName('body');var body = elems[0];$('#notifications').append(Strophe.getText(body));}return true;
}

这个函数应位于在 清单 26 中定义的 onConnect 函数上方。

最终效果

在一个 web 浏览器中打开您的 index.html 文件。您应该会看到一个简单的标题和一条消息,该消息称更新将在下面显示(这可能会使您回想起您发给自己的测试通知,称 XMPP 连接正在成功运行)。

现在加载 backend.php。就像变戏法一样,来自 IBM developerWorks Web development 专区的最新更新将显示在您的页面上。其他带有 RSS 提要的示例源包括 Twitter 帐户、通讯社、以及来自服务器监控软甲的更新提要。

这是开发一个强大平台的简单起点。Strophe.js 能够促进应用程序的双向通信,尽管更简单的方法是使用标准的 jQuery HTTP 回拨来将用户输入送入系统,从而避免为您的应用程序编写一个 XMPP 后台监控进程的麻烦。更令人兴奋的是,当您 web 服务器用作 BOSH 代理时,完全无需太多来自服务器端 web 应用程序的输入,两个或更多 web 客户端就能通过 XMPP 相互通信。这种技术将对从办公室协作软件到游戏的很多软件产生深远影响。

Code

var BOSH_SERVICE = '/xmpp-httpbind'
var connection = null;

function notifyUser(msg) 
{
    if (msg.getAttribute('from') == "testuser@127.0.0.1/pingstream") {
    var elems = msg.getElementsByTagName('body');
    var body = elems[0];
    $('#notifications').append(Strophe.getText(body));
    }
return true;
}

function onConnect(status)
{
if (status == Strophe.Status.CONNECTED) {
$('#notifications').html('<p class="welcome">Hello! Any new posts will appear below.</p>');
connection.addHandler(notifyUser, null, 'message', null, null,  null);
connection.send($pres().tree());
}
}

$(document).ready(function () {
    connection = new Strophe.Connection(BOSH_SERVICE);
    connection.connect( "receivinguser@127.0.0.1",
    "receivinguserpass",
    onConnect);
    });

xmpp bosh web相关推荐

  1. java xmpp smack_如何使用java smack库连接XMPP bosh服务器?

    我使用strophe.js在webapp上运行xmpp客户端,根据我的用例场景我必须快速切换到不同的页面 当前的方法并不安全,因为jid和密码在java脚本中是可见的,我正在寻找解决方案来在strop ...

  2. xmpp协议(即时通信协议规范)

    转载自 https://www.cnblogs.com/jiyuqi/p/5085932.html 相关背景 IM(Instant Messaging)正在被广泛使用,特别是公司与它们的客户互动连接方 ...

  3. xmpp服务器性能测试,使用JMeter测试XMPP聊天服务器

    我正在寻找使用JMeter在XMPP/HTTP Web服务服务器上执行一些性能和负载测试.我是JMeter的新手,现在我已经开始了解基础知识,但是我希望尽快完成这些测试并尽快运行,以便获得一些帮助.使 ...

  4. Openfire配置过程,以及与php交互注意事项。

    使用 XMPP 构建一个基于 web 的通知工具 转 使用 XMPP 构建一个基于 web 的通知工具 使用 XMPP.PHP 和 JavaScript 编写实时 web 应用程序 Ben Werdm ...

  5. 即时通讯学习笔记001---XMPP了解认知

    JAVA技术交流QQ群:170933152 XMPP 简单介绍 本小节将简要介绍 XMPP,它的起源.以及为何它是一个适合实时 web 通信的协议.您将检查 XMPP 通信设置的组件,并查看展示这些组 ...

  6. Android 进阶技术汇总二: 流行框架组件 方案汇总

    前言:应用框架组件概述: 主要介绍移动应用开发涉及 推送.语音识别.音视频.图片.地图.定位.广告接入.后台统计分析.HTTP通信.分享.支付.数据解析.序列化.消息总线等 WebApp Cordov ...

  7. Android优秀开源项目汇总

    UI相关 图片 Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载.缓存.显示图片 ImageLoader:co ...

  8. androud 常用组件

    UI相关 图片 Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载.缓存.显示图片 ImageLoader:co ...

  9. Android常用组件收集

    UI相关 图片 Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载.缓存.显示图片 ImageLoader:co ...

最新文章

  1. 微信支付HTTPS服务器证书验证(PHP)
  2. DSX2-5000 CH测试结果使用福禄克LinkWare Live软件的好处
  3. weakreference_Java中WeakReference,SoftReference,PhantomReference和Strong Reference之间的区别...
  4. 电信设置的nat 虚拟服务器192.168.1.3 是什么,VMware WorkStation的三种网络连接方式详解...
  5. mysql 树形结构_Mysql安装:基础入门知识
  6. 传奇私服DBC2000合并数据库时删除重复Name关键字SQL指令
  7. Deepin字体下载与安装
  8. java手机解锁密码_Appium 解决手势密码 (java篇)
  9. 手动获取我们所感兴趣网站X.509证书的一般方法
  10. Flash 0day漏洞(CVE-2018-5002)千万不要乱打开Excel文档!
  11. 【unity 保卫星城】--- 开发笔记(Demo演示篇)
  12. KuPlay:社区运营会是下一个风口吗?
  13. fping命令-ping整个网段所有IP
  14. 浅析GIS行业地图绘制基本要求
  15. element ui 中级联选择器,点击完下拉框收回
  16. python通过关键字搜索淘宝商品详细信息
  17. he/she, him/her 和 his/hers 等等的使用
  18. WIFI码生成附近门店团长分销CPS优惠券流量主小程序开发
  19. PVE世界常见的存储格式,qcow2/raw/vmdk
  20. java基于微信小程序的公交线路查询系统 uniapp 小程序

热门文章

  1. 创业,不是狗咬狗—leo看赢在中国第三季 3
  2. 软件工程开课第一周博客
  3. 瞄准私有云市场的“博云 BoCloud”,获数千万元 A 轮战略投资
  4. 自己写的调用Onboard-SDK-master中大疆API控制无人机210飞行并SDK中记录飞行高度、四元数的程序
  5. 产品经理手要低,解决用户问题才是核心
  6. C++容器--std::set
  7. List、Set、Map 之间的区别是什么?
  8. Atheros-CSI-Tool(Ubuntu版本安装及使用过程)[原教程来自xieyaxiong]
  9. Hightchart 实现 polar 雷达图
  10. 杨海成--互联网时代的工业发展新思维及德国工业