【问题标题】:Cometd javascript client doesn't subscribe to broadcast channelCometd javascript客户端不订阅广播频道
【发布时间】:2014-02-07 19:33:19
【问题描述】:

javascript 客户端似乎无法订阅广播频道或接收来自它的消息。下面是 spring-cometd 服务代码,在收到来自外部事件的消息后,在 notification 频道上广播消息。 java-cometd 客户端可以成功接收到广播消息。甚至 javascript 客户端也可以在 服务频道 上发布和订阅消息,但不能在广播频道上。握手后订阅完成。

JavaScript 代码:

  var cometd = $.cometd;



  cometd.addListener('/meta/handshake', _metaHandshake);// handshake listener
        cometd.addListener('/meta/connect', _metaConnect);//connection connect listener
        cometd.addListener('/meta/disconnect', _metaDisconnect); 
        cometd.handshake();



  function _metaHandshake(handshake)
            {
                if (handshake.successful === true)  
                {


                    cometd.batch(function()
                    {


                cometd.subscribe('/notification', function(m) {alert("hi"); });



                    });
                }

javascript 客户端订阅广播频道时会出现什么问题。

@javax.inject.Named // Tells Spring that this is a bean
@javax.inject.Singleton // Tells Spring that this is a singleton
@Service("notificationService")
public class NotificationService {

    private static final String channelName="/notification";
    private static ServerChannel serverChannel;
    private Logger logger = Logger.getLogger(this.getClass());

    @Inject
    private BayeuxServer bayeuxServer;

    @Session
    private LocalSession session;



    @PostConstruct
    public void init()
    {
        logger.debug("Notification Service Initialized");
        channelSetUp();
        session = bayeuxServer.newLocalSession("external");
        session.handshake();

    }


    public void channelSetUp()
    {

        MarkedReference<ServerChannel> channelCreated = bayeuxServer.createChannelIfAbsent(channelName, new ServerChannel.Initializer()
        {
        public void configureChannel(ConfigurableServerChannel channel)
        {
            channel.setPersistent(true);// channel persistent
            channel.addAuthorizer(GrantAuthorizer.GRANT_SUBSCRIBE_PUBLISH); 
        }
        });

        if(channelCreated.isMarked())
        {
            serverChannel = bayeuxServer.getChannel(channelName);

        }
    }






    public void onExternalEvent( Map<String, Object> data)
    {


        // ServerChannel serverChannel = this.bayeuxServer.getChannel(channelName);

    // logger.debug("Notify MessageData from JMS ::" + data.toString());
    if (serverChannel != null)
        {
           // Broadcast the data
        serverChannel.publish(session, data, null);

        }


    }



    @Listener(Channel.META_SUBSCRIBE)  
    public void processSubscription(ServerSession remote, ServerMessage message)
    {   
        // What channel the client wants to subscribe to ?
       String channel = (String)message.get(Message.SUBSCRIPTION_FIELD);
       logger.debug("Client Channel ::"+channel);

    }




}

【问题讨论】:

    标签: java spring dojo cometd


    【解决方案1】:

    您的客户端代码是正确的。

    您的服务器代码可以改进,特别是:

    • 您无需在 init() 中创建本地会话:@Session 注释会为您完成。
    • 您无需在init() 中调用channelSetup():只需使用@Configure 注释即可。
    • 您不需要存储对ServerChannel 的引用:因为您使通道持久化,所以在onExternalEvent() 中只需执行:bayeuxServer.getChannel(channelName).publish(...);

    如果您已正确遵循 Spring integration 的文档,并避免创建文档中描述的 2 个 BayeuxServer 实例(使用 Spring 时的典型错误),那么您应该很高兴。

    我建议您在客户端和服务器中都enable debug logging,并查看日志,这应该可以解释为什么您的 JavaScript 客户端没有收到消息。

    希望有所帮助!

    【讨论】:

    • 经过分析,真正的问题是cometd javascript客户端只有在cometd服务器启动之前订阅了客户端才能接收到广播消息。当服务器上的java程序开始广播并且cometd javascript稍后订阅。客户端无法接收广播消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多