Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)

本文主要是介绍Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://ju.outofmemory.cn/entry/110340


β
登录 注册
阿里云服务器,值得信赖    京东招聘运维工程师,待遇丰厚    服务器只买阿里云140万企业与开发者的信赖

Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)

姜糖水 2015-01-14 1695 阅读
web开发

XMPP(Extensible Messaging and Presence Protocol)是一种网络即时通讯协议,它基于XML,具有很强的扩展性,被广泛使用在即时通讯软件、网络游戏聊天、Web聊天及Web消息推送、移动设备的消息推送等场景,例如Google的GTalk、《英雄联盟LOL》游戏聊天模块。

由于在Web浏览器上的JavaScript不能直接处理TCP协议,所以XMPP服务器通常会提供BOSH(Bidirectional-streams Over Synchronous HTTP)接口,通过HTTP长轮训(long-polling)可以实现Web浏览器即时聊天。Strophe.js是一个通过BOSH连接Web浏览器和XMPP服务器的工具库。

XMPP协议简介:

XMPP服务器和客户端之间,是通过XML节(XML Stanza)来进行通讯。其中有三种非常重要的XML Stanza类型:<message>、<presence>、<iq>。

<message>:

聊天消息的发送和接收就是通过message节来实现。例如xxg1@host发送一条信息”你好”给xxg2@host,xxg1@host客户端会将下面的这段XML发送到XMPP服务器,服务器再推送给xxg2@host客户端。其中<message>的from属性是发送者,to属性是接收者,<body>子元素的内容就是聊天信息。

<message from="xxg1@host" to="xxg2@host" type="chat"><body>你好</body>
</message>

<presence>:

可用于表明用户的状态,例如用户状态改变成“Do not disturb”(“请勿打扰”),会向服务器发送:

<presence from="xxg@host"><status>Do not disturb</status><priority>0</priority><show>dnd</show>
</presence>

<iq>:

iq即Info/Query,采用“请求-响应”机制,类似于HTTP的机制。下面的例子是客户端通过<iq>请求获取联系人,XMPP服务器将结果返回:

客户端请求获取联系人:

<iq from='xxg@host' id='bv1bs71f' type='get'><query xmlns='jabber:iq:roster'/>
</iq>

服务器结果返回:

<iq to='xxg@host' id='bv1bs71f' type='result'><query xmlns='jabber:iq:roster'><item jid='xxg2@host'/><item jid='xxg3@host'/></query>
</iq>

搭建XMPP服务器:

在实现Web浏览器聊天之前,首先要搭建一个XMPP服务器。例如Openfire、Tigase、Ejabberd是常用的XMPP服务器。其中Openfire、Tigase是基于Java实现,Ejabberd是Erlang实现。虽然实现的语言不同,但是都遵循XMPP协议,所以使用其中任意一个XMPP服务器即可。

下面以Openfire和Tigase为例。

Openfire可以自动化搭建很方便,本文不再介绍。Tigase的搭建可以参考我的另一篇博文:Linux搭建XMPP服务器Tigase(Spark客户端测试)。

XMPP服务器通常会实现BOSH扩展,下面是Openfire和Tigase的BOSH默认URL:

Openfire:http://host:7070/http-bind
Tigase:http://host:5280

在使用Strophe.js的时候,需要使用对应的HTTP地址才能连接上XMPP服务器。

如果使用Opnefire,还需要在管理后台配置一下:

Strophe.js:

下载:http://strophe.im/strophejs/

实现Web私聊:

私聊比较简单,聊天信息是通过上面介绍的<message>来进行传递交换。例如接收到一条别人发来的聊天信息,即接收一个<message>元素,发送给别人一条聊天信息,即发送一个<message>元素。

HTML:

<!DOCTYPE html>
<html>
<head><script src="http://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script><script src="http://cdn.bootcss.com/strophe.js/1.1.3/strophe.min.js"></script><script src="http://www.cnphp6.com/archives/test.js"></script>
</head>
<body>JID:<input type="text" id="input-jid"><br>密码:<input type="password" id="input-pwd"><br><button id="btn-login">登录</button><div id="msg" style="height: 400px; width: 400px; overflow: scroll;"></div>联系人JID:<input type="text" id="input-contacts"><br>消息:<br><textarea id="input-msg" cols="30" rows="4"></textarea><br><button id="btn-send">发送</button>
</body>
</html>

JavaScript(test.js):

// XMPP服务器BOSH地址
var BOSH_SERVICE = 'http://host:5280';// XMPP连接
var connection = null;// 当前状态是否连接
var connected = false;// 当前登录的JID
var jid = "";// 连接状态改变的事件
function onConnect(status) {console.log(status)if (status == Strophe.Status.CONNFAIL) {alert("连接失败!");} else if (status == Strophe.Status.AUTHFAIL) {alert("登录失败!");} else if (status == Strophe.Status.DISCONNECTED) {alert("连接断开!");connected = false;} else if (status == Strophe.Status.CONNECTED) {alert("连接成功,可以开始聊天了!");connected = true;// 当接收到<message>节,调用onMessage回调函数connection.addHandler(onMessage, null, 'message', null, null, null);// 首先要发送一个<presence>给服务器(initial presence)connection.send($pres().tree());}
}// 接收到<message>
function onMessage(msg) {// 解析出<message>的from、type属性,以及body子元素var from = msg.getAttribute('from');var type = msg.getAttribute('type');var elems = msg.getElementsByTagName('body');if (type == "chat" && elems.length > 0) {var body = elems[0];$("#msg").append(from + ":<br>" + Strophe.getText(body) + "<br>")}return true;
}$(document).ready(function() {// 通过BOSH连接XMPP服务器$('#btn-login').click(function() {if(!connected) {connection = new Strophe.Connection(BOSH_SERVICE);connection.connect($("#input-jid").val(), $("#input-pwd").val(), onConnect);jid = $("#input-jid").val();}});// 发送消息$("#btn-send").click(function() {if(connected) {if($("#input-contacts").val() == '') {alert("请输入联系人!");return;}// 创建一个<message>元素并发送var msg = $msg({to: $("#input-contacts").val(), from: jid, type: 'chat'}).c("body", null, $("#input-msg").val());connection.send(msg.tree());$("#msg").append(jid + ":<br>" + $("#input-msg").val() + "<br>");$("#input-msg").val('');} else {alert("请先登录!");}});
});

修改JavaScript代码中的BOSH_SERVICE,用浏览器打开HTML文件,登录后即可聊天:

实现Web群聊:

XMPP群聊通过XMPP协议的MUC(Multi-User Chat)扩展实现。

Openfire默认支持MUC,但是Tigase服务器默认不支持MUC,需要在init.properties文件中加入以下粗体部分的配置项:

config-type=–gen-config-def
–admins=admin@host
–virt-hosts = host
–debug=server
–user-db=mysql
–user-db-uri = jdbc:mysql://localhost:3306/tigasedb?user=root&password=xxx
–comp-name-1 = muc
–comp-class-1 = tigase.muc.MUCComponent
–external = muc.devel.tigase.org:muc-pass:connect:5270:devel.tigase.org:accept

创建房间:

创建房间实际上可以写在代码中,但是本文为了方便,就使用XMPP客户端Spark或者其他工具来创建。

首先使用Spark任意登录一个用户,下图是Spark创建房间的步骤:

如果使用的是Tigase,默认创建的房间是加锁的,别的用户无法进入,需要对房间解锁。Spark进入房间后,点击下面的设置按钮,然后不用更改任何设置,直接更新即可解锁房间(虽然没有修改任何配置,但是更新时会发送一个<iq>给服务器,这个<iq>解锁了房间,参考http://xmpp.org/extensions/xep-0045.html#createroom-instant):

另外,如果使用Openfire可以直接使用管理后台来创建:

加入房间:

房间创建好了之后,就有有对应的房间JID:

加入房间可以通过发送一个<presence>来实现(实际上如果房间不存在下面的这条<presence>也会创建房间,但是创建的房间默认加锁,还需要发送一条<iq>解锁,所以本文就直接用Spark创建房间):

<presence from='xxg@host' to='xxgroom@muc.host/xxg'><x xmlns='http://jabber.org/protocol/muc'/>
</presence>

属性to=’xxgroom@muc.host/xxg’中,xxgroom@muc.host表示房间JID,xxg表示在房间的昵称。

聊天:

和私聊一样,群聊也是通过<message>来实现,不同的是<message>的type属性,私聊是”chat”,而群聊是”groupchat”,另外,to属性即为房间JID,这样一条聊天消息就会发送给房间中的所有人。

<message from='xxg@host' to='myroom@muc.host' type='groupchat'><body>大家好!</body>
</message>

实现:

HTML:

<!DOCTYPE html>
<html>
<head><script src="http://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script><script src="http://cdn.bootcss.com/strophe.js/1.1.3/strophe.min.js"></script><script src="http://www.cnphp6.com/archives/test2.js"></script>
</head>
<body>JID:<input type="text" id="input-jid"><br>密码:<input type="password" id="input-pwd"><br><button id="btn-login">登录</button><div id="msg" style="height: 400px; width: 400px; overflow: scroll;"></div><br>消息:<br><textarea id="input-msg" cols="30" rows="4"></textarea><br><button id="btn-send">发送</button>
</body>
</html>

JavaScript(test2.js):

// XMPP服务器BOSH地址
var BOSH_SERVICE = 'http://host:5280';// 房间JID
var ROOM_JID = 'xxgroom@muc.host';// XMPP连接
var connection = null;// 当前状态是否连接
var connected = false;// 当前登录的JID
var jid = "";// 连接状态改变的事件
function onConnect(status) {if (status == Strophe.Status.CONNFAIL) {alert("连接失败!");} else if (status == Strophe.Status.AUTHFAIL) {alert("登录失败!");} else if (status == Strophe.Status.DISCONNECTED) {alert("连接断开!");connected = false;} else if (status == Strophe.Status.CONNECTED) {alert("连接成功,可以开始聊天了!");connected = true;// 当接收到<message>节,调用onMessage回调函数connection.addHandler(onMessage, null, 'message', null, null, null);// 首先要发送一个<presence>给服务器(initial presence)connection.send($pres().tree());// 发送<presence>元素,加入房间connection.send($pres({from: jid,to: ROOM_JID + "/" + jid.substring(0,jid.indexOf("@"))}).c('x',{xmlns: 'http://jabber.org/protocol/muc'}).tree());}
}// 接收到<message>
function onMessage(msg) {console.log(msg);// 解析出<message>的from、type属性,以及body子元素var from = msg.getAttribute('from');var type = msg.getAttribute('type');var elems = msg.getElementsByTagName('body');if (type == "groupchat" && elems.length > 0) {var body = elems[0];$("#msg").append(from.substring(from.indexOf('/') + 1) + ":<br>" + Strophe.getText(body) + "<br>")}return true;
}$(document).ready(function() {// 通过BOSH连接XMPP服务器$('#btn-login').click(function() {if(!connected) {connection = new Strophe.Connection(BOSH_SERVICE);connection.connect($("#input-jid").val(), $("#input-pwd").val(), onConnect);jid = $("#input-jid").val();}});// 发送消息$("#btn-send").click(function() {if(connected) {// 创建一个<message>元素并发送var msg = $msg({to: ROOM_JID, from: jid, type: 'groupchat'}).c("body", null, $("#input-msg").val());connection.send(msg.tree());$("#input-msg").val('');} else {alert("请先登录!");}});
});

创建好房间,修改JavaScript代码中的BOSH_SERVICE和ROOM_JID,用浏览器打开HTML文件,登录后即可群聊:

另外,Strophe.js还有一个专门的MUC插件,有兴趣的同学可以自己研究下:https://github.com/strophe/strophejs-plugins/tree/master/muc。

web开发
作者:姜糖水
又一个码农站点
原文地址: Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC), 感谢原作者分享。
→二叉排序树的插入与删除 ←基于jQuery的美食时间轴焦点图插件

发表评论

© 2015 内存溢出
复制代码
保存代码

这篇关于Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/402726

相关文章

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

MySQL中的分组和多表连接详解

《MySQL中的分组和多表连接详解》:本文主要介绍MySQL中的分组和多表连接的相关操作,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录mysql中的分组和多表连接一、MySQL的分组(group javascriptby )二、多表连接(表连接会产生大量的数据垃圾)MySQL中的

Python实现微信自动锁定工具

《Python实现微信自动锁定工具》在数字化办公时代,微信已成为职场沟通的重要工具,但临时离开时忘记锁屏可能导致敏感信息泄露,下面我们就来看看如何使用Python打造一个微信自动锁定工具吧... 目录引言:当微信隐私遇到自动化守护效果展示核心功能全景图技术亮点深度解析1. 无操作检测引擎2. 微信路径智能获

Python中pywin32 常用窗口操作的实现

《Python中pywin32常用窗口操作的实现》本文主要介绍了Python中pywin32常用窗口操作的实现,pywin32主要的作用是供Python开发者快速调用WindowsAPI的一个... 目录获取窗口句柄获取最前端窗口句柄获取指定坐标处的窗口根据窗口的完整标题匹配获取句柄根据窗口的类别匹配获取句

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll