2014-08-29 211 views
4

我正在開發一個實時通知系統通過的WebSockets使用彈簧4配置的WebSocket服務器。在春季4

的源代碼如下:

WebSocketConfig:

@Configuration 
@EnableScheduling 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 

    @Override 
    public void registerStompEndpoints(StompEndpointRegistry registry) { 
     registry.addEndpoint("/lrt").withSockJS(); 
    } 

    @Override 
    public void configureMessageBroker(MessageBrokerRegistry registry) { 
     registry.enableSimpleBroker("/queue/", "/topic/"); 
     registry.setApplicationDestinationPrefixes("/app"); 
    } 

} 

LRTStatusListener:

@Service 
public class LRTStatusListener implements ApplicationListener<BrokerAvailabilityEvent>{ 

    private static final Logger LOG = LoggerFactory.getLogger(LRTStatusListener.class); 
    private final static long LRT_ID = 1234567890; 
    private final static String LRT_OWNER = "Walter White"; 
    private final LRTStatusGenerator lrtStatusGenerator = new LRTStatusGenerator(LRT_ID, LRT_OWNER); 
    private final MessageSendingOperations<String> messagingTemplate; 
    private AtomicBoolean brokerAvailable = new AtomicBoolean(); 

    @Autowired 
    public LRTStatusListener(MessageSendingOperations<String> messagingTemplate) { 
     this.messagingTemplate = messagingTemplate; 
    } 

    @Override 
    public void onApplicationEvent(BrokerAvailabilityEvent event) { 
     this.brokerAvailable.set(event.isBrokerAvailable()); 
    } 

    @Scheduled(fixedDelay=2000) 
    public void sendLRTStatus() { 
     LRTStatus lrtStatus = this.lrtStatusGenerator.generateLRTStatus(); 
     if (LOG.isTraceEnabled()) 
      LOG.trace("Sending LRT status"); 
     if (this.brokerAvailable.get()) 
      this.messagingTemplate 
       .convertAndSend("/topic/status" + lrtStatus.getLRTId(), lrtStatus); 
    } 

    // Random status generator 
    private static class LRTStatusGenerator { 

     private LRTStatus lrtStatus; 

     public LRTStatusGenerator(long lrtId, String owner) { 
      lrtStatus = new LRTStatus(lrtId, owner, getCurrentTimestamp(), generateLRTStatusMessage()); 
     } 

     public LRTStatus generateLRTStatus() { 
      lrtStatus.setMessage(generateLRTStatusMessage()); 
      return lrtStatus; 
     } 

     private String getCurrentTimestamp() { 
      Date date = new Date(); 
      Timestamp timestamp = new Timestamp(date.getTime()); 
      return timestamp.toString(); 
     } 

     private String generateLRTStatusMessage() { 
      String statusMessage; 
      switch ((int) Math.random() * 2) { 
      case 1: 
       statusMessage = 
         "HANK: What? You want me to beg? You're the smartest guy I ever met. " + 
         "And you're too stupid to see... he made up his mind ten minutes ago."; 
       break; 
      case 2: 
       statusMessage = 
         "WALTER: That's right. Now say my name. " + 
         "- DECLAN: ...You're Heisenberg. - WALTER: You're goddamn right."; 
       break; 
      default: 
       statusMessage = 
         "WALTER: I am not in danger, Skyler. I am the danger! " + 
         "A guy opens his door and gets shot and you think that of me? " + 
         "No. I am the one who knocks!"; 
       break; 
      } 
      return statusMessage; 
     } 

    } 

} 

CheckLRTStatusController

@Controller 
public class CheckLRTStatusController { 

    @MessageExceptionHandler 
    @SendToUser("/topic/errors") 
    public String handleException(Throwable exception) { 
     return exception.getMessage(); 
    } 

} 

應用程序通過每2000ms更改其信息來模擬長時間運行事務(LRT)的狀態。現在

,我定義了一個客戶端通過SockJS測試的WebSocket:

<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script> 
<script> 
    var sock = new SockJS('/lrt'); 
    sock.onopen = function() { 
     console.log('open'); 
    }; 
    sock.onmessage = function(e) { 
     console.log('message', e.data); 
    }; 
    sock.onclose = function() { 
     console.log('close'); 
    }; 
</script> 

的連接工作正常,但我無法看到數據流。

如何正確配置我的應用程序以生成並在客戶端控制檯上路由由WebSocket服務器發送的消息?

請注意,我還在使用內置的Message Broker,目的是管理消息隊列。

回答

4

這是您目前擁有的唯一的JavaScript代碼?:

<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script> 
<script> 
    var sock = new SockJS('/lrt'); 
    sock.onopen = function() { 
     console.log('open'); 
    }; 
    sock.onmessage = function(e) { 
     console.log('message', e.data); 
    }; 
    sock.onclose = function() { 
     console.log('close'); 
    }; 
</script> 

認爲只有建立在SockJS與回退的連接,但不訂閱消息代理。你也需要這樣做。

在當前的設置,您有:

registry.enableSimpleBroker("/queue/", "/topic/"); 

您需要創建一個JavaScript STOMP客戶端(超過SockJS),對於那些簽約,是這樣的:

stompClient.subscribe("/topic/status*", function(message) { 
    ... 
}); 

stompClient.subscribe("/queue/whatever", function(message) { 
    ... 
}); 

看一看的spring-websocket-portfolio申請一個完整的工作示例。

+0

服務器端代碼是否正確? – vdenotaris 2014-08-30 12:14:06

+0

@vdenotaris:乍一看,它看起來不錯 – Bogdan 2014-08-30 13:05:26