【发布时间】:2020-12-05 20:30:02
【问题描述】:
我有一个使用 web-sockets 和 stomp 的 Spring Boot 应用程序,由于 ISAM 设置的限制,我必须使用 xhr-polling 协议,并且此应用程序将托管在 Pivotal Cloud Foundry (PCF) 上。
当我运行单个实例时,使用以下代码(如下)一切正常。
服务器
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/dummy");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry
.addEndpoint("/dummyendpoint")
.setAllowedOrigins("*")
.withSockJS();
}
}
客户
var socket,client;
socket = new SockJS('http://localhost:8080/dummyendpoint');
client = Stomp.over(socket);
client.connect({}, function () {
client.subscribe('/dummy/message', function (message) {
console.log('subscribed');
}
});
但是,如果我扩展到 2 个实例,web-socket 连接开始失败:
GET localhost:8080/dummyendpoint/info -> Status 200
POST localhost:8080/dummyendpoint/300/jskdncdj/xhr -> Status 200 OK
POST localhost:8080/dummyendpoint/300/jskdncdj/xhr_send -> Status 204
POST localhost:8080/dummyendpoint/300/jskdncdj/xhr_send -> Status 404
我一直在查看发布的其他问题,例如Spring Websocket in a tomcat cluster,我实施了他们的解决方案,但没有成功。
我一直在阅读spring-session,它看起来支持网络套接字(如果我没看错?)。
我已经尝试将 spring-session 与 Redis 和有/没有 RabbitMQ 作为消息代理一起使用:
public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<Session>{
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry
.enableStompBrokerRelay("/topic")
.setRelayHost("localhost")
.setRelayPort(61613)
.setClientLogin("guest")
.setClientPasscode("guest");
}
@Override
public void configureStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry
.addEndpoint("/dummyendpoint")
.setAllowedOrigins("*")
.withSockJS();
}
}
我尝试过的一切总是以同样的错误结束:
GET localhost:8080/dummyendpoint/info -> Status 200
POST localhost:8080/dummyendpoint/300/jskdncdj/xhr_streaming -> Status 200 Aborted
POST localhost:8080/dummyendpoint/300/jskdncdj/xhr_send -> Status 204
POST localhost:8080/dummyendpoint/300/jskdncdj/xhr_send -> Status 404
有人知道我为什么会收到此错误吗?
我猜这是因为我正在连接到实例 1,而另一个请求正在命中另一个实例?
我是否可以在使用xhr-polling 时垂直和水平缩放应用程序?
谢谢
斯彭斯
【问题讨论】:
-
查看在浏览器的 DevTools 中发送的请求,并查看请求中的 cookie。查看是否正在设置
JSESSIONID和__VCAP_ID__。这表明 Gorouter 正在使用粘性会话,并将始终将您的请求路由到相同的后端应用程序实例。使用 WebSockets,您不必担心这一点,因为它只是一个持久连接,但是使用长轮询,您可以这样做,因为它是多个 HTTP 请求。如果您将请求粘贴到同一个后端实例,那可能会有所帮助。 -
请记住,Spring 的简单 stomp 代理是在内存中的,因此如果您想添加更多实例(这也可能是您获得 404 的原因),它将无法工作。如果您希望能够合法地使用多个应用程序实例,则需要使用 RabbitMQ 或其他一些外部 stomp 代理。这篇文章很好地解释了为什么。 stackoverflow.com/a/43174082/1585136
标签: spring-websocket long-polling cloud-foundry spring-session