2016-03-04 5 views
4


Я использую spring-websocket и spring-messaging (версия 4.2.2.RELEASE) для реализации STOMP над веб-сайтами с полнофункциональным брокером (Apache ActiveMQ 5.10.0).
Мои клиенты предназначены для ПОДПИСАТЬ только в пункты назначения - то есть они должны не иметь возможности отправлять сообщения SEND. Кроме того, я хотел бы реализовать более строгий контроль над тем, на какие адресаты могут подписаться мои клиенты. В любом случае (то есть, когда клиент пытается отправить сообщение или подписаться на недопустимое назначение) Я хотел бы быть в состоянииКак закрыть веб-узел STOMP на весеннем сервере

  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) Throw исключение из 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 для отправки кадра STORP ERROR? и 2) как вы разорвать/закрыть websocket? – Nenad

+0

@Nenad обновил ответ, попробуйте вторую часть и сообщите мне, если это сработает. – Karthik

+0

@ Kathrik, если я сделаю исключение, чем я бы отказался от контроля потока и не смог бы отключиться. Вы знаете, есть ли способ отправки кадра ERROR без исключения исключения? – Nenad

 Смежные вопросы

  • Нет связанных вопросов^_^