2014-02-07 37 views
0

看来,javascript客户端无法订阅广播频道或收到广播频道。以下是在收到来自外部事件的消息后,在通知通道上广播消息的spring-cometd服务代码。 java-cometd客户端可以成功接收广播消息。即使javascript客户端也可以在服务频道上发布和订阅消息,但不能在广播频道上发布消息。订阅是在握手后完成的。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); 

    } 




} 

回答

0

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

你的服务器代码可以得到改善,特别是:

  • 你不需要在init()创建一个本地会话:在@Session注释会为你。
  • 您无需在init()中拨打channelSetup():只需使用@Configure注释。
  • 你并不需要参考存储到ServerChannel:因为你所做的通道执着,在onExternalEvent()只是做:bayeuxServer.getChannel(channelName).publish(...);

如果遵循正确的Spring integration的文档,并避免创造在文档中描述的2个BayeuxServer实例(使用Spring时出现的典型错误),那么你应该很好。

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

希望有帮助!

+0

经过分析,真正的问题是只有当客户端订阅cometd服务器启动之前,cometd javascript客户端才能收到广播消息。当服务器上的java程序启动广播并在稍后订阅cometd javascript时。客户端无法接收广播消息。 – user2263197