2016-03-04 77 views
4


我使用spring-websocket和spring-messaging(版本4.2.2.RELEASE)通過具有全功能代理的websockets實現STOMP(Apache ActiveMQ 5.10.0 )。
我的客戶是指訂閱僅限目的地 - 那就是他們不應該應該能夠發送消息。此外,我想對我的客戶可以訂閱的目的地實施更嚴格的控制。在這兩種情況下(即當客戶端試圖將消息發送或訂閱一個無效的目的地)我想能夠如何在彈簧服務器上關閉STOMP websocket

  1. 發送一個適當的錯誤,和/或
  2. 關閉的WebSocket

請注意,我的所有目標被轉發到ActiveMQ的。我以爲我可以實現對入站通道ChannelInterceptor,但看着我無法弄清楚如何實現我想要的API。這是否可能,以及驗證客戶端請求的最佳方法是什麼? 我的WebSocket配置低於:

<websocket:message-broker 
    application-destination-prefix="/app"> 
    <websocket:stomp-endpoint path="/pushchannel"/> 
    <websocket:stomp-broker-relay relay-host="localhost" 
     relay-port="61613" prefix="/topic" 
     heartbeat-receive-interval="300000" heartbeat-send-interval="300000" /> 
    <websocket:client-inbound-channel> 
     <websocket:interceptors> 
      <bean class="MyClientMessageInterceptor"/> 
     </websocket:interceptors> 
    </websocket:client-inbound-channel> 
</websocket:message-broker> 

回答

0

你可以寫一個入站攔截,併發送相應的錯誤信息給客戶端。

public class ClientInboundChannelInterceptor extends ChannelInterceptorAdapter { 

@Autowired 
private SimpMessagingTemplate simpMessagingTemplate; 

@Override 
public Message<?> preSend(Message message, MessageChannel channel) throws IllegalArgumentException{ 
    StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message); 
    logger.debug("logging command " + headerAccessor.getCommand()); 
    try { 
      //write your logic here 
     } catch (Exception e){ 
      throw new MyCustomException(); 
     } 
    } 

} 

UPDATE:

1)當您從ClientInboundChannelInterceptor拋出任何異常,它將被作爲ERROR幀發送,你沒有做什麼特別的。

2)我不確定關閉連接,但做一些像創建DISCONNECT標題和發送它應該工作(我會嘗試測試這個和更新答案)。

SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.DISCONNECT); 
headerAccessor.setSessionId(sessionId); 
headerAccessor.setLeaveMutable(true); 

template.convertAndSendToUser(destination,new HashMap<>(),headerAccessor.getMessageHeaders()); 

您在訂閱時發送錯誤時有以下選項之一。

1)從ClientInboundChannelInterceptor拋出異常。

2)在你的Handler/Controller,添加@SubscribeMapping並返回框架。

@SubscribeMapping("your destination") 
public ConnectMessage handleSubscriptions(@DestinationVariable String userID, org.springframework.messaging.Message message){ 
    // this is my custom class 
    ConnectMessage frame= new ConnectMessage(); 
    // write your logic here 
    return frame; 
} 

frame將被直接發送到客戶端。

+0

然而,這是一個好主意,1)您如何使用SimpMessagingTemplate發送STOMP ERROR幀?和2)你如何撕裂-ff /關閉websocket? – Nenad

+0

@Nenad更新了答案,嘗試第二部分,並讓我知道它是否有效。 – Karthik

+0

@Kathrik如果我把比我將放棄線程的控制和不能夠做一個分離異常。你知道是否有一種方法發送錯誤幀沒有拋出異常? – Nenad

相關問題