如何关闭弹簧服务器中的STOMP websocket

Nen*_*nad 5 java stomp spring-messaging spring-websocket


我正在使用spring-websocket和spring-messaging(版本4.2.2.RELEASE)通过功能齐全的代理(Apache ActiveMQ 5.10.0)在websockets上实现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>
Run Code Online (Sandbox Code Playgroud)

Kar*_*hik 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();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

更新:

1)当你抛出任何异常时ClientInboundChannelInterceptor,它将作为ERROR帧发送,你不必做任何特殊的事情。

2)我不确定是否要关闭连接,但是做一些诸如创建DISCONNECT标头并发送它之类的事情应该可行(我将尝试测试这一点并更新答案)。

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

template.convertAndSendToUser(destination,new HashMap<>(),headerAccessor.getMessageHeaders());
Run Code Online (Sandbox Code Playgroud)

您可以使用以下选项之一在订阅时发送错误。

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;
}
Run Code Online (Sandbox Code Playgroud)

frame将直接发送给客户。