2014-08-29 4 views
4

Я разрабатываю систему оповещения в режиме реального времени через WebSockets с помощью Spring 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(); 
    } 

} 

Приложение имитирует статус долговременной транзакции (LRT), изменяя свою информацию каждые 2000 мс.

Теперь я тестирование WebSocket путем определения клиента с помощью SockJS:

<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

+0

@vdenotaris: на первый взгляд, он выглядит нормально – Bogdan