2014-08-29 210 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