2014-02-07 41 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