我有两个Java进程,我在春季启动时使用websocket连接它们。一个进程充当客户端并像这样连接:
List<Transport> transports = new ArrayList<Transport>(1);
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
WebSocketClient client = new SockJsClient(transports);
WebSocketStompClient stompClient = new WebSocketStompClient(client);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
StompSessionHandler firstSessionHandler = new MyStompSessionHandler("Philip");
stompClient.connect("ws://localhost:8080/chat", firstSessionHandler);
会话处理程序扩展了StompSessionHandlerAdapter并提供了这些方法(我正在通过用户名进行订阅,因此每个客户端都可以接收自己的消息):
@Override
public void afterConnected(
StompSession session, StompHeaders connectedHeaders) {
session.subscribe("/user/" + userName + "/reply", this);
session.send("/app/chat", getSampleMessage());
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
Message msg = (Message) payload;
// etc.....
}
在服务器端,我暴露了一个控制器,并且正在通过从工作线程调用终结点来写数据。
@Autowired
private SimpMessagingTemplate template;
@MessageMapping("/chat")
public void send(
Message message)
throws Exception {
template.convertAndSendToUser(message.getFrom(),
"/reply",
message);
}
在websocket配置中,我重写了设置限制的方法:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic", "/user");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setMessageSizeLimit(500 * 1024);
registration.setSendBufferSizeLimit(1024 * 1024);
registration.setSendTimeLimit(20000);
}
我的问题是,如果服务器上的负载足够高并且我超出了限制,则websocket将会灾难性地失败,因此我想避免这种情况。我想做的是使控制器能够询问消息代理“此消息是否适合缓冲区?”,以便我可以限制在限制之下。我搜索了API文档,但看不到任何方法。我还有其他明显的解决方案吗?
谢谢。
实际上我找到了一种解决方案,所以如果有人对此感兴趣,就在这里。
在websocket的服务器端配置上,我在出站通道(这是API的一部分)上安装了一个Interceptor,在从嵌入式代理每次发送之后都会调用它。