CometD是基于Dojo、jQuery等JS库的一个开源实时通讯框架,能够提供基于事件的、低延时的客户端-服务器通讯。该框架支持多种传输方式,例如长轮询、WebSocket等。接下来,我们将以CometD jQuery Demo为例,介绍如何使用CometD进行实时通讯。
$(document).ready(function () {
var cometd = $.cometd;
function _connectionInitialized() {
$('#body').append('CometD Connection Established');
}
function _connectionBroken() {
$('#body').append('CometD Connection Broken');
}
function _connectionClosed() {
$('#body').append('CometD Connection Closed');
}
function _metaHandshake(handshake) {
if (handshake.successful === true) {
$('#body').append('CometD Handshake Successful');
} else {
$('#body').append('CometD Handshake Failed');
}
}
var cometURL = location.protocol + "//" + location.host + config.contextPath + "/cometd";
cometd.configure({
url: cometURL,
logLevel: 'debug'
});
cometd.addListener('/meta/handshake', _metaHandshake);
cometd.addListener('/meta/unsuccessful', function (message) {
console.debug('unsuccessful', message);
});
cometd.addListener('/meta/connect', function (message) {
if (message.successful === true) {
_connectionInitialized();
} else {
_connectionBroken();
}
});
cometd.addListener('/meta/disconnect', _connectionClosed);
cometd.handshake();
});
首先,在页面加载完成时,我们要定义一个CometD实例,以及一些回调函数。其中,_connectionInitialized
、_connectionBroken
和_connectionClosed
会分别在连接建立、连接中断和连接关闭时被调用。而_metaHandshake
则是一个特殊的回调函数,在成功/失败握手时被调用。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CometD jQuery Demo</title>
<script src="${pageContext.request.contextPath}/resources/js/jquery-3.3.1.min.js"></script>
<script src="${pageContext.request.contextPath}/resources/js/org/cometd.js"></script>
<script src="${pageContext.request.contextPath}/resources/js/org/cometd/jquery/jquery.cometd.js"></script>
</head>
<body id="body"></body>
</html>
接下来,我们需要在页面中引入jQuery和CometD的JS库,并定义一个ID为body的DOM元素。
最后,我们需要在服务端实现一个CometD的终端节点,用于处理客户端发送的消息。
public class CometDEndpoint extends BayeuxServerImpl {
public CometDEndpoint() {
BayeuxServerImpl impl = new BayeuxServerImpl();
impl.addExtension(new TimestampExtension());
setSecurityPolicy(new DefaultSecurityPolicy());
}
public void init() {
Endpoint cometdServletEndpoint = new ServletEndpoint();
cometdServletEndpoint.setServletPath("/cometd/*");
cometdServletEndpoint.setServer(this);
cometdServletEndpoint.init();
}
class ServletEndpoint extends AbstractBayeuxServletPathAware {
@Override
protected BayeuxServerImpl getBayeux() {
return (BayeuxServerImpl) CometDEndpoint.this;
}
}
}
这里,我们创建了一个CometDEndpoint
类,继承自BayeuxServerImpl,并实现了一个init
方法,用于初始化CometD的终端节点。在此方法中,我们定义了一个ServletEndpoint
类,继承自AbstractBayeuxServletPathAware,并重写了所需的方法。其中,setServletPath
方法是用于定义CometD的URL路径,而setServer
方法则是用于与BayeuxServerImpl
之间建立联系。最后,我们可以将该方法添加到应用程序的初始化中,以便在应用程序启动时被自动调用。