Cometd JavaScript客户端不订阅广播频道 [英] Cometd javascript client doesn't subscribe to broadcast channel

查看:233
本文介绍了Cometd JavaScript客户端不订阅广播频道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

似乎JavaScript客户端无法订阅广播频道或从中收到消息。以下是从外部事件接收消息后,在通知频道上广播消息的spring-cometd服务代码。 java-cometd客户端可以正常接收广播消息。即使是JavaScript客户端也可以在服务渠道上发布和订阅消息,但不能在广播频道上发布。订阅完成后握手。

It seems that the javascript client cannot subscribe to the broadcast channel or receive the message from it. Below is the spring-cometd service code that broadcast the message on the notification channel after receiving message from external event. The java-cometd client can receive the broadcast messages sucessfuly. Even the javascript client can publish and subscribe the messages on service channels but not on broadcast channel. The subscription is done after the handshake.

JavaScript代码:

JavaScript Code:

  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客户端订阅广播频道时,会出现什么问题。 >

What could go wrong when javascript client subscribe to the broadcast channel.

@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);

    }




}


推荐答案

您的客户端代码正确。

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

Your server code can be improved, in particular:


  • 您不需要在 init()中创建本地会话: @Session 注释为您提供。

  • 您不需要调用 channelSetup() $ init():只需使用 @Configure 注释。

  • 您不需要存储对 ServerChannel 的引用:由于您在 onExternalEvent()只需执行: bayeuxServer.getChannel(channelName).publish(...);

  • You don't need to create a local session in init(): the @Session annotation does it for you.
  • You don't need to call channelSetup() in init(): just use a @Configure annotation.
  • You don't need to store a reference to the ServerChannel: since you made the channel persistent, in onExternalEvent() just do: bayeuxServer.getChannel(channelName).publish(...);

如果您已正确遵循 Spring Integration ,并避免创建2 Bayeu xServer 实例(使用Spring的典型错误)在文档中描述,那么你应该很好去。

If you have followed correctly the documentation for the Spring integration, and avoided the creation of 2 BayeuxServer instances (a typical error when using Spring) described in the documentation, then you should be good to go.

我建议你<客户端和服务器中的href =http://docs.cometd.org/reference/troubleshooting.html =nofollow>启用调试日志,并查看日志,这些应该解释为什么JavaScript客户端没有收到消息。

I suggest that you enable debug logging in both client and server, and look at the logs, that should explain why your JavaScript client does not receive the messages.

希望有帮助!

这篇关于Cometd JavaScript客户端不订阅广播频道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆