何以笙箫默电影音乐:CometD的JavaScript订阅

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 06:15:18

原文地址:

                 http://cometd.org/documentation/cometd-javascript/subscription

 

CometDJavaScript订阅

raman在周一,2009629 - 15:29提交。

 

JavaScriptCometD API:订阅和取消订阅

 

频道

 

Bayeux规范定义了频道的概念:它像一个消息的主题,有兴趣的人士可以订阅接收到频道发布的信息。

 3种类型的渠道:

 元数据频道

 服务频道

 正常频道

 

一个频道看起来像一个目录路径,如/meta/connect(元数据频道;所有的元数据频道的前缀都是/meta/开始的),或/service/chat(服务频道;所有服务频道的前缀都是/service/开始的)或/foo/bar(正常频道)。

 

元数据频道

 

元数据频道由Bayeux协议本身创建。

订阅元数据频道这是不可能的:服务器将回复一条错误消息。但是,它可能监听元数据频道(见下文订阅和监听之间的差异)。

发布消息到元数据频道是没有意义的:只有Bayeux协议实现创建和发送元数据频道的消息。

 元数据频道对客户端监听错误消息是非常有用的,像握手错误(例如,因为客户端没有提供正确的凭据)或网络错误(例如,知道什么时候与服务器的连接断开了,或它已经重新建立了)。

 

服务频道

 

服务频道在客户端和服务器以请求/响应的方式进行通信的情况下使用(对应于发布/订阅的方式进行通信或正常频道)。

 订阅服务频道不会得到错误,这相当于对服务器没有操作:服务器会忽略订阅请求。

 它可以用特定的客户端(一个发布消息到服务频道的客户端)和服务器之间通信的语义发布消息到服务频道。

 服务频道是很有用的实现,例如,私人聊天消息:在与userAuserBuserC聊天,userA可以使用服务频道发布私人消息给userCUserB不会知道)。

 

正常频道

 

正常频道,有一个消息主题的语义,并在发布/订阅的通信方式情况下使用。

 通常情况下,是可以订阅正常频道和发布消息到正常频道的,只有在bayeux服务器上使用了安全策略才会禁止。

正常频道在实现广播消息给所有订阅的客户中是非常有用的,例如,在股票价格变动的情况下。

 

订阅者与听众

 

JavaScriptCometD API2API来让频道订阅工作:

 addListener()和removeListener()

 subscribe()和unsubscribe()

 

addListener()方法:

 监听元数据频道的消息必须使用

 可用于收听服务频道消息(你也可以使用subscribe())

 不应该用来听正常频道消息(使用subscribe()代替)

 不涉及任何与bayeux服务器的通信,因此可以调用之前称为握手的handshake()

 是同步的:当它返回时,要保证监听已添加

 

subscribe()方法:

 不得用于收听元数据频道消息(否则服务器将返回一个错误)

 可用于收听服务频道消息(你也可以使用addListener())

 应该用来监听正常频道消息

 涉及bayeux服务器的通信,因此不能在调用握手handshake()之前调用

是异步的:它会立即返回,在bayeux服务器已收到订阅请求之前

 

请注意:

调用subscribe(),当subscribe()返回时,并不意味着您已经完成了与服务器的订阅。

 

addListener()和subscribe()都返回一个订阅对象,必须分别通过removeListener()和unsubscribe()来取消订阅:

 / /一些初始化代码

var subscription1= cometd.addListener('/meta/connect', function() { ... });

var subscription2= cometd.subscribe('/foo/bar/', function() { ... });

 

/ /一些初始化代码

cometd.unsubscribe(subscription2);

cometd.removeListener(subscription1);

 

 一个常见的模式是利用幂等方法来处理,像这样:

 var _subscription;

 

// The idempotentmethod

function_refresh()

{

    _appUnsubscribe();

    _appSubscribe();

}

 

function_appUnsubscribe()

{

    if (_subscription)

        cometd.unsubscribe(_subscription);

    _subscription = null;

}

 

function_appSubscribe()

{

    _subscription =cometd.subscribe('/foo/bar', function() { ... });

}

 当然,同样也适用于addListener()/ removeListener()。

 

需要指出的是,你要小心你的应用程序:你一定要取消订阅,以避免泄漏函数或不止一次执行函数(因为你可能会错误地绑定两次相同的回调)。

 请参阅讨论有关使用幂等方法的思想。

 

bayeux服务器不可达的情况下,怎么处理subscribe()和unsubscribe()(由于网络故障,或因为服务器崩溃)?

 subscribe()中。本地监听是第一个加入到该频道的用户列表的,然后服务器企图与它进行通信。如果通信失败,服务器将不知道,它已经将消息发送到这个客户端,因此客户端上的本地监听(虽然目前还是)将永远不会被调用。

 unsubscribe(),本地监听是首次从该频道的用户列表中删除的,然后服务器企图与它通信。如果通信失败,服务器仍然会发送消息到客户端,但不会有本地监听派遣。

 

侦听/订阅的异常处理

 

如果侦听或订阅函数抛出一个异常(例如,调用一个未定义的对象,方法等),然后记录错误消息(“调试”级别)。

 然而,有一种方法:定义一个全局监听器的异常处理程序,拦截每次侦听或订阅抛出的异常:

 cometd.onListenerException =function(exception, subscriptionHandle, isListener, message)

{

    // Uh-oh, something went wrong, disablethis listener/subscriber

    // Object "this" points to theCometD object

    if (isListener)

       this.removeListener(subscriptionHandle);

    else

        this.unsubscribe(subscriptionHandle);

}

 

监听器的异常处理程序可以发送消息到服务器。

 如果监听器异常处理程序本身抛出一个异常,这个异常记录为“信息”且不破坏CometD实现。

 需要注意的是有一个类似的机制扩展存在,

http://cometd.org/documentation/cometd/ext可以看到。

 

通配符订阅

 

可以一次使用通配符来订阅几个频道,比如:

 cometd.subscribe("/chatrooms/*",function(message) { ... });

 

 一个星号的意思是匹配一个单一频道段,所以在上面的例子,它将匹配频道/chatrooms/12 /chatrooms/15, 而不是 /chatrooms/12/upload

  为了匹配多个频道细分,使用两个星号:

 cometd.subscribe("/events/**",function(message) { ... });

 

两个星号将匹配/events/stock/FOO /events/forex/EUR, 以及 /events/feed /events/feed/2009/08/03

 

通配符机制也适用于侦听,因此很这样可能侦听所有的元数据频道:

 cometd.addListener("/meta/*",function(message) { ... });

 

 默认情况下,订阅全局通配符/ * / **返回的结果是一个错误,但这种行为在通过给bayeux服务器指定一个自定义安全政策来改变。

 

通配符只能被指定在频道的最后部分,所以这些都是无效的订阅:/ ** / foo/ foo /*/bar

 

元数据频道列表

 

这些都是在JavaScript CometD实现的元数据频道:

 /meta/handshake

 /meta/connect

 /meta/disconnect

 /meta/subscribe

 /meta/unsubscribe

 /meta/publish

 /meta/unsuccessful

 

 

当记录的bayeux消息由JavaScript Cometd实现处理时,每一个元数据频道就会被通知。

有任何失败都会通知/meta/unsuccessful频道。

 

到目前为止,最有趣的是订阅/meta/connect元数据频道,因为它能返回与bayeux服务器的当前连接状态。它可以和/meta/disconnect组合使用。例如,根据bayeux服务器上的连接状态,在页面上显示一个绿色的“连接”图标或一个红色的“断开”图标,。

 

使用/meta/connect /meta/disconnect频道,这是一种常见的模式:

 

var _connected =false;

 

cometd.addListener('/meta/connect',function(message)

{

    // if (cometd.getStatus() == 'disconnecting'|| cometd.getStatus() == 'disconnected')

    if (cometd.isDisconnected()) // Availablesince 1.1.2

    {

        return;

    }

    var wasConnected = _connected;

    _connected = message.successful;

    if (!wasConnected && _connected)

    {

        // Reconnected

    }

    else if (wasConnected &&!_connected)

    {

        // Disconnected

    }

});

 

cometd.addListener('/meta/disconnect',function(message)

{

    if (message.successful)

    {

        _connected = false;

    }

}

 /meta/connect频道的一个小的需要注意的是/meta/connect是使用轮询服务器。

 因此,如果断开是在一个活动的轮询期间,这个轮询将被服务器返回,并触发/meta/connect监听器。

 执行连接逻辑前不进行状态的初步检查验证。

 

元数据频道的另一种有趣的用法是在握手时,有一个身份验证步骤。

在注册/meta/handshake频道情况下,可以返回相关细节,例如,验证失败的细节。