@Override
 protected StompHeaders processConnectHeaders(StompHeaders connectHeaders) {
   connectHeaders = super.processConnectHeaders(connectHeaders);
   if (connectHeaders.isHeartbeatEnabled()) {
     Assert.state(
         getTaskScheduler() != null, "TaskScheduler must be set if heartbeats are enabled");
   }
   return connectHeaders;
 }
 @Override
 public Type getPayloadType(StompHeaders stompHeaders) {
   // Tries to determine the payload type based on the destination of the message
   // You can add more cases below if you want to listen to any more channels,
   // But make sure you subscribe to it first
   String destination = stompHeaders.getDestination();
   switch (destination) {
     case "/user/queue/player":
       return PlayerInfo.class;
     case "/user/queue/errors":
       return BlackjackErrorWrapper.class;
     case "/topic/game":
       return GameInfoWrapper.class;
     default:
       return Object.class;
   }
 }
 @Override
 public void handleFrame(StompHeaders headers, Object payload) {
   Object thePayload = payload;
   if (thePayload == null) {
     thePayload = headers.getFirst(StompHeaderAccessor.STOMP_MESSAGE_HEADER);
   }
   if (thePayload != null) {
     Message<?> failedMessage =
         getMessageBuilderFactory()
             .withPayload(thePayload)
             .copyHeaders(headerMapper.toHeaders(headers))
             .build();
     MessagingException exception =
         new MessageDeliveryException(failedMessage, "STOMP frame handling error.");
     logger.error("STOMP frame handling error.", exception);
     if (applicationEventPublisher != null) {
       applicationEventPublisher.publishEvent(
           new StompExceptionEvent(StompMessageHandler.this, exception));
     }
   }
 }
 @Override
 public void handleFrame(StompHeaders headers, Object payload) {
   Exception ex = new Exception(headers.toString());
   logger.error("STOMP ERROR frame", ex);
   this.failure.set(ex);
 }
  @Override
  protected void handleMessageInternal(final Message<?> message) throws Exception {
    try {
      connectIfNecessary();
    } catch (Exception e) {
      throw new MessageDeliveryException(
          message, "The [" + this + "] could not deliver message.", e);
    }
    StompSession stompSession = this.stompSession;

    StompHeaders stompHeaders = new StompHeaders();
    this.headerMapper.fromHeaders(message.getHeaders(), stompHeaders);
    if (stompHeaders.getDestination() == null) {
      Assert.state(
          this.destinationExpression != null,
          "One of 'destination' or 'destinationExpression' must be"
              + " provided, if message header doesn't supply 'destination' STOMP header.");
      String destination =
          this.destinationExpression.getValue(this.evaluationContext, message, String.class);
      stompHeaders.setDestination(destination);
    }

    final StompSession.Receiptable receiptable =
        stompSession.send(stompHeaders, message.getPayload());
    if (receiptable.getReceiptId() != null) {
      final String destination = stompHeaders.getDestination();
      if (this.applicationEventPublisher != null) {
        receiptable.addReceiptTask(
            new Runnable() {

              @Override
              public void run() {
                StompReceiptEvent event =
                    new StompReceiptEvent(
                        StompMessageHandler.this,
                        destination,
                        receiptable.getReceiptId(),
                        StompCommand.SEND,
                        false);
                event.setMessage(message);
                applicationEventPublisher.publishEvent(event);
              }
            });
      }
      receiptable.addReceiptLostTask(
          new Runnable() {

            @Override
            public void run() {
              if (applicationEventPublisher != null) {
                StompReceiptEvent event =
                    new StompReceiptEvent(
                        StompMessageHandler.this,
                        destination,
                        receiptable.getReceiptId(),
                        StompCommand.SEND,
                        true);
                event.setMessage(message);
                applicationEventPublisher.publishEvent(event);
              } else {
                logger.error(
                    "The receipt ["
                        + receiptable.getReceiptId()
                        + "] is lost for ["
                        + message
                        + "] on destination ["
                        + destination
                        + "]");
              }
            }
          });
    }
  }