最近要做一个直播的礼物功能。刚开始打算使用websocket去实现数据的时效性,但是考虑到后期的并发以及pc+h5+app三端的对接,最终选用 ejabberd作为服务,ejabberd是基于Jabber/XMPP协议的即时通讯服务器,是可扩展性最好的一种Jabber/XMPP服务器,支持分布多个服务器,并且具有容错处理,单台服务器失效不影响整个cluster运作。
最初,同事给了一个converse.js作为web端的客户端,但由于对此不熟,加之converse.js的耦合性较高,不容易实现个性化定制(可能是我太菜了。。。)。最终,选择了Strophe.js作为web端的客户端,一路艰辛,特此记录。
html代码
// XMPP服务器BOSH地址
var BOSH_SERVICE = 'http://192.168.1.204:5280/http-bind/';
// 房间JID
var ROOM_JID = '[email protected]';
// 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;
// 当接收到
connection.addHandler(onMessage, null, 'message', null, null, null);
// 首先要发送一个
connection.send($pres().tree());
// 发送
var pres = $pres({
from: jid,
to: ROOM_JID + "/" + jid.substring(0,jid.indexOf("@"))
}).c('x',{xmlns: 'http://jabber.org/protocol/muc'}).tree();
connection.send(pres);
//connection.sendIQ(pres);//获取房间列表
}
}
// 接收到
function onMessage(msg) {
console.log(msg);
// 解析出
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) + ":
" + Strophe.getText(body) + "
")
}
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) {
// 创建一个
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("请先登录!");
}
});
});