英文:
Websockets using "SockJS+spring websocket" error when trying to connect the websocket (404: path of STOMP endpoint not found)
问题
以下是您提供的内容的翻译:
在我的网络应用程序中,我尝试使用SockJS连接到WebSocket,但返回了错误消息(404路径"/stomp/info"未找到):
这个问题已经被问过很多次了,但我没有找到适合我情况的答案。
有人能帮我找到解决方案吗?
这是我的代码
- 基于Spring WebFlux、Spring Security(JWT)的服务器端 [Spring Boot 版本:2.1.2 RELEASE]
WebSocketConfig.java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/prob");
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/prob");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/stomp")
.setAllowedOrigins("http://localhost:4200")
//.setAllowedOrigins("*")
.withSockJS();
}
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(new ObjectMapper());
converter.setContentTypeResolver(resolver);
messageConverters.add(converter);
return false;
}
}
CORSFilter.java
@Configuration
@EnableWebFlux
public class CORSFilter implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.exposedHeaders("Access-Control-Allow-Origin",
"Access-Control-Allow-Methods",
"Access-Control-Allow-Headers",
"Access-Control-Max-Age",
"Access-Control-Request-Headers",
"Access-Control-Request-Method")
.maxAge(3600)
.allowCredentials(false);
}
}
WebSecurityConfig.java
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
@Configuration
public class WebSecurityConfig {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private SecurityContextRepository securityContextRepository;
@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
return http
.cors().and().headers().frameOptions().disable().and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.authenticationManager(authenticationManager)
.securityContextRepository(securityContextRepository)
.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.pathMatchers("/login","/stomp","/stomp/**","/stomp/info","/stomp/info/**").permitAll()
.anyExchange().authenticated()
.and().build();
}
}
- 基于Angular的客户端(stompjs + sockjs-client)
socketConnect() {
const socket = new SockJS('http://localhost:8081/stomp');
this.stompClient = StompJS.Stomp.over(socket);
const _this = this;
this.stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
_this.stompClient.subscribe('/prob/' + _this.id + '/newcomment', function (data) {
console.log(data);
});
});
}
更新
我更改了CORS过滤器的配置:
@Configuration
public class CORSFilter {
@Bean
CorsWebFilter corsWebFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:4200");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
但我仍然遇到另一个错误:
>GET http://localhost:8081/stomp/info?t=1602859336795 404 (未找到)
以下是服务器端初始化WebSocket的日志:
2020-10-16 15:41:14.712 INFO 13060 --- [ restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting...
2020-10-16 15:41:14.712 INFO 13060 --- [ restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [DefaultSubscriptionRegistry[cache[0 destination(s)], registry[0 sessions]]]]
2020-10-16 15:41:14.714 INFO 13060 --- [ restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Started.
...
2020-10-16 15:42:13.750 INFO 13060 --- [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
英文:
In my web application, i tried to connect to the websocket using SockJS, but an error message is returned (404 path "/stomp/info" not found) :
This question is asked numerous times, but i fail to find an answer for my situation
Could anyone help me to find the solution ?
Here is my code
- Server side based on spring web flux, spring security (JWT) [spring boot version: 2.1.2RELEASE]
WebSocketConfig.java
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/prob");
registry.setApplicationDestinationPrefixes("/app");
registry.setUserDestinationPrefix("/prob");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/stomp")
.setAllowedOrigins("http://localhost:4200")
//.setAllowedOrigins("*")
.withSockJS();
}
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(new ObjectMapper());
converter.setContentTypeResolver(resolver);
messageConverters.add(converter);
return false;
}
}
CORSFilter.java
@Configuration
@EnableWebFlux
public class CORSFilter implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*")
.exposedHeaders("Access-Control-Allow-Origin",
"Access-Control-Allow-Methods",
"Access-Control-Allow-Headers",
"Access-Control-Max-Age",
"Access-Control-Request-Headers",
"Access-Control-Request-Method")
.maxAge(3600)
.allowCredentials(false);
}
}
WebSecurityConfig.java
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
@Configuration
public class WebSecurityConfig {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private SecurityContextRepository securityContextRepository;
@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
return http
.cors().and().headers().frameOptions().disable().and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.authenticationManager(authenticationManager)
.securityContextRepository(securityContextRepository)
.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.pathMatchers("/login","/stomp","/stomp/**","/stomp/info","/stomp/info/**").permitAll()
.anyExchange().authenticated()
.and().build();
}
}
- Client side based on Angular (stompjs + sockjs-client)
socketConnect() {
const socket = new SockJS('http://localhost:8081/stomp');
this.stompClient = StompJS.Stomp.over(socket);
const _this = this;
this.stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
_this.stompClient.subscribe('/prob/' + _this.id + '/newcomment', function (data) {
console.log(data);
});
});
}
UPDATE
I changed the configuration of the CORS Filter :
@Configuration
public class CORSFilter{
@Bean
CorsWebFilter corsWebFilter(){
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://localhost:4200");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",config);
return new CorsWebFilter(source);
}
But i still having an other error :
>GET http://localhost:8081/stomp/info?t=1602859336795 404 (not found)
Here is the logs of initialization of websocket in the server side :
2020-10-16 15:41:14.712 INFO 13060 --- [ restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Starting...
2020-10-16 15:41:14.712 INFO 13060 --- [ restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [DefaultSubscriptionRegistry[cache[0 destination(s)], registry[0 sessions]]]]
2020-10-16 15:41:14.714 INFO 13060 --- [ restartedMain] o.s.m.s.b.SimpleBrokerMessageHandler : Started.
...
2020-10-16 15:42:13.750 INFO 13060 --- [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
答案1
得分: 1
最后我找到了问题,
问题是我在spring-mvc中使用了websocket配置而不是spring-webflux,我找到了一个很好的教程,可以在spring-webflux的响应式上下文中实现websocket:链接描述在此
英文:
And finally i found the issue,
the problem is i used websocket configuration for spring-mvc and not spring-webflux, i found a good tuto to implement websocket in reactive context with spring-webflux : enter link description here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论