2017-09-13 9 views
1

SpringとSimpleBrokerの実装(外部ブローカーを利用しない)に基づくWebsocket-stompサーバーがあります。Spring Websocket STOMP:RECEIPTフレームを送信

私はSTOMP RECEIPTメッセージを有効にしたいと思います。

これを自動的に送信するようにコードを設定する方法はありますか?

//SimpleBrokerMessageHandler doesn't support RECEIPT frame, hence we emulate it this way 
    @Bean 
    public ApplicationListener<SessionSubscribeEvent> webSocketEventListener(
      final AbstractSubscribableChannel clientOutboundChannel) { 
     return event -> { 
      Message<byte[]> message = event.getMessage(); 
      StompHeaderAccessor stompHeaderAccessor = StompHeaderAccessor.wrap(message); 
      if (stompHeaderAccessor.getReceipt() != null) { 
       stompHeaderAccessor.setHeader("stompCommand", StompCommand.RECEIPT); 
       stompHeaderAccessor.setReceiptId(stompHeaderAccessor.getReceipt()); 
       clientOutboundChannel.send(
         MessageBuilder.createMessage(new byte[0], stompHeaderAccessor.getMessageHeaders())); 
      } 
     }; 
    } 

https://github.com/spring-projects/spring-integration/blob/master/spring-integration-stomp/src/test/java/org/springframework/integration/stomp/inbound/StompInboundChannelAdapterWebSocketIntegrationTests.java

答えて

2

。レシートヘッダーで受信フレームをキャプチャする別の方法があります。 @EnableWebSocketMessageBrokerアノテーションを持つクラスだけを拡張する必要があり、他のクラス(@Controllerアノテーションを持つクラスなど)は同じままです。それはとoutChannelを得ることは非常にエレガントではありません必要以上

import java.util.logging.Level; 
import java.util.logging.Logger; 
import java.util.Map; 
import java.util.List; 
import java.util.HashMap; 
import java.util.ArrayList; 

import org.springframework.context.annotation.Configuration; 
import org.springframework.messaging.simp.config.MessageBrokerRegistry; 
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; 
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; 
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; 
import org.springframework.messaging.simp.config.SimpleBrokerRegistration; 
import org.springframework.messaging.Message; 
import org.springframework.messaging.MessageHeaders; 
import org.springframework.messaging.support.ChannelInterceptorAdapter; 
import org.springframework.messaging.support.GenericMessage; 
import org.springframework.messaging.simp.config.ChannelRegistration; 
import org.springframework.messaging.simp.SimpMessageType; 
import org.springframework.messaging.simp.stomp.StompCommand; 
import org.springframework.messaging.MessageChannel; 
import org.springframework.beans.factory.annotation.Autowired; 

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 

    private static final Logger LOGGER = Logger.getLogger(WebSocketConfig.class.getName()); 
    private MessageChannel outChannel; 

    @Override 
    public void configureClientInboundChannel(ChannelRegistration registration) { 
     registration.interceptors(new InboundMessageInterceptor()); 
    } 

    @Override 
    public void configureClientOutboundChannel(ChannelRegistration registration) { 
     registration.interceptors(new OutboundMessageInterceptor()); 
    } 

    @Override 
    public void configureMessageBroker(MessageBrokerRegistry config) { 
// prefixes are application-dependent 
     config.enableSimpleBroker("/topic"); 
     config.setApplicationDestinationPrefixes("/app"); 
    } 

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


    class InboundMessageInterceptor extends ChannelInterceptorAdapter { 

     @SuppressWarnings("unchecked") 
     public Message preSend(Message message, MessageChannel channel) { 
      LOGGER.log(Level.SEVERE, "preSend: "+message); 
      GenericMessage genericMessage = (GenericMessage)message; 
      MessageHeaders headers = genericMessage.getHeaders(); 
      String simpSessionId = (String)headers.get("simpSessionId"); 
      if((SimpMessageType.MESSAGE.equals(headers.get("simpMessageType")) && 
        StompCommand.SEND.equals(headers.get("stompCommand"))) || 
       (SimpMessageType.SUBSCRIBE.equals(headers.get("simpMessageType")) && 
        StompCommand.SUBSCRIBE.equals(headers.get("stompCommand"))) && 
       (simpSessionId != null)) { 
       Map<String,List<String>> nativeHeaders = (Map<String,List<String>>)headers.get("nativeHeaders"); 
       if(nativeHeaders != null) { 
        List<String> receiptList = nativeHeaders.get("receipt"); 
        if(receiptList != null) { 
         String rid = (String)receiptList.get(0); 
         LOGGER.log(Level.SEVERE, "receipt requested: "+rid); 
         sendReceipt(rid, simpSessionId); 
        } 
       } 
      } 
      return message; 
     } 

     private void sendReceipt(String rid, String simpSessionId) { 
      if(outChannel != null) { 
       HashMap<String,Object> rcptHeaders = new HashMap<String,Object>(); 
       rcptHeaders.put("simpMessageType", SimpMessageType.OTHER); 
       rcptHeaders.put("stompCommand", StompCommand.RECEIPT); 
       rcptHeaders.put("simpSessionId", simpSessionId); 
       HashMap<String,List<String>> nativeHeaders = new HashMap<String,List<String>>(); 
       ArrayList<String> receiptElements = new ArrayList<String>(); 
       receiptElements.add(rid); 
       nativeHeaders.put("receipt-id", receiptElements); 
       rcptHeaders.put("nativeHeaders",nativeHeaders); 
       GenericMessage<byte[]> rcptMsg = new GenericMessage<byte[]>(new byte[0],new MessageHeaders(rcptHeaders)); 
       outChannel.send(rcptMsg); 
      } else 
       LOGGER.log(Level.SEVERE, "receipt NOT sent"); 
     } 
    } 

    class OutboundMessageInterceptor extends ChannelInterceptorAdapter { 
     public void postSend(Message message, 
      MessageChannel channel, 
      boolean sent) { 
      LOGGER.log(Level.SEVERE, "postSend: "+message); 
      outChannel = channel; 
     } 
    } 
} 

確かに、それははるかに複雑です。しかし、それは動作します。 :-)

0

フレームをSUBSCRIBEためアルテムビランが提供する答えはのみ動作します:STOMPプロトコルのために、我々はこのコードを持って春の統合テストで

関連する問題