【问题标题】:CometD + Java + jQuery: Too much publishes with one callCometD + Java + jQuery:一次调用发布太多
【发布时间】:2012-02-16 13:47:25
【问题描述】:

您好,我遇到了下一个问题,使用 cometd + jquery + java 在广播消息中进行了一些测试。

这是我的 web.xml,我使用的是 cometd 的 Annotations 实现:

<!-- Cometd Servlet -->
<servlet>
    <servlet-name>cometd</servlet-name>
    <servlet-class>org.cometd.java.annotation.AnnotationCometdServlet</servlet-class>
    <init-param>
        <param-name>timeout</param-name>
        <param-value>60000</param-value>
    </init-param>
    <init-param>
        <param-name>logLevel</param-name>
        <param-value>3</param-value>
    </init-param>
    <init-param>
        <param-name>services</param-name>
        <param-value>com.api.services.UserStatusService</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>
<servlet-mapping>
    <servlet-name>cometd</servlet-name>
    <url-pattern>/do/cometd/*</url-pattern>
</servlet-mapping>

这是我注册的服务:

package com.api.services;

import java.util.HashMap;

import javax.inject.Inject;

import org.cometd.bayeux.Message;
import org.cometd.bayeux.client.ClientSession;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.java.annotation.Service;
import org.cometd.java.annotation.Session;
import org.cometd.java.annotation.Subscription;

@Service
public class UserStatusService
{
    @Inject
    private BayeuxServer bayeux;
    @Session
    private ClientSession bayeuxClient;

    @Subscription("/userStatus")
    public void userStatus (Message message)
    {
        HashMap<String, String> mapa = new HashMap<String,String>();
        String channel = message.getChannel();
        System.out.println("*** The Channel is "+channel+" ***");
        ClientSessionChannel chann = bayeuxClient.getChannel(channel);
        mapa.put("canal", channel);
        mapa.put("mensaje", "Hola Wi!!");
        mapa.put("ServChan", bayeux.getChannels().get(0).toString());
        chann.publish(mapa);
    }
}

这是我用来订阅和发布的 JS jQuery 代码(是更大对象的一部分,所以我只是粘贴与此相关的主要内容):

     /** On document ready i call this one **/
     initBroad:function(){
    $.cometd.unregisterTransport('websocket');
    $.cometd.init('http://localhost/MyApp/do/cometd');
    console.log("Set cometd initialization");
    main.broadListener();
},
count:0,
subscription:null,
refresh:function(){
    this.appUnsubscribe();
    this.appSubscribe();
},
appUnsubscribe:function(){
    if (this.subscription) 
        $.cometd.unsubscribe(this.subscription);
    this.subscription = null;
},
appSubscribe:function(){
    func = function(msg){
                    /** I had to do this in order to avoid ALL the 500 times it does it :S **/
        if(main.count < 1){
            console.log(main.count + ": " +  msg.data.mensaje);
        }
        main.count++;
    };
    this.subscription = $.cometd.subscribe("/userStatus",func);
},
broadListener:function(){
    console.log("Set the broadListener");
    main.refresh();
},
publishBroad:function(){
    main.refresh();
    $.cometd.publish('/userStatus', {mensaje:"Hola"});
},

好吧,在尝试通过控制台运行方法 publishBroad 之后,它实际上运行了,但是在服务器中只需单击/请求 450-500 次(是的,它只是从浏览器到 java 服务器的一个请求,450 -500 次仅在服务器端重复,并在响应中多次到达浏览器)!!

我做错了什么?我使用的是 cometd 官方网站上最新的 cometd.js 和 jquery.cometd.js。

另外,当我在控制台中检查这个(我使用 JBoss AS7)时,我留下了一些输出日志行来查看我的调用是否进入了方法(Sys out println 说 The Channel is:. 它还显示在 JBoss 控制台中记录行 450-500 次!

谁能帮我解决这个问题?

谢谢!!

【问题讨论】:

  • 不知道怎么了,我注意到if (this._subscription) $.cometd.unsubscribe(this.subscription); this.subscription = null; 我想你有一个额外的下划线
  • 谢谢我已经更正了那行,但我仍然遇到问题,通过一次调用 js cometd 发布方法,我在服务器中的服务上接到了大约 500 次调用:(跨度>

标签: jquery ajax comet cometd


【解决方案1】:

您的问题是您在服务中使用了 ClientSession。

如果在您的服务中,您只想回复发件人,请执行以下操作:

@Service
public class UserStatusService
{
    @Session
    private LocalSession session;

    @Subscribe("/userStatus")
    public void userStatus(ServerSession remoteClient, ServerMessage message)
    {
        Map<String, String> map = new HashMap<String,String>();
        map.put("mensaje", "Hola Wi!!");
        remoteClient.deliver(session, message.getChannel(), map, null);
    }
}

请参考CometD concepts以了解ClientSession、ServerSession和LocalSession之间的区别,并参考annotated services

您注意到循环的原因(1 个请求导致服务执行 500 次以上)是因为如果您的服务在最后一行重新广播到同一频道。

【讨论】:

  • 谢谢,我会试试的,即使经过各种阅读和你所看到的混淆,我也不能很好地理解 Cometd 文档中的概念,我会让你知道 :)
  • 顺便说一句,我现在记得,我的想法是向该频道的所有订阅发送通知,这就是为什么我没有使用 remoteClient.deliver 方法,我想办法联系他们是使用发布方法,我要更仔细地阅读文档,看看发生了什么
猜你喜欢
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多