I have a Spring Boot application running in a Docker container on Azure Container Instances. This application uses SockJS and STOMP for WebSocket connections. The WebSocket endpoint is configured at /ws.
Backend Configuration
**WebConfig for CORS:
package com.vaisala.xweatherobserve.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(@NonNull CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("http://localhost:3000", "http://barn-backend-dns.northeurope.azurecontainer.io")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true);
}
}
WebSocketConfig:
package com.vaisala.xweatherobserve.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(@NonNull StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("http://localhost:3000")
.withSockJS();
}
@Override
public void configureMessageBroker(@NonNull MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
SecurityConfig:
package com.vaisala.xweatherobserve.config;
import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.authorizeHttpRequests(authorizeRequests -> authorizeRequests
.requestMatchers("/ws/**").permitAll()
.anyRequest().authenticated())
.sessionManagement(sessionManagement -> sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
return http.build();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(Collections.singletonList("http://localhost:3000"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Problem:
When I try to connect to the WebSocket endpoint using wscat, I get a 400 Bad Request error:
bash
Code kopieren
wscat -c ws://my-backend-dns.northeurope.azurecontainer.io:8080/ws
error: Unexpected server response: 400
Additionally, when I access the WebSocket URL via a browser, I see the message “Welcome to SockJS!”.
Frontend Code:
import { useEffect, useState } from 'react';
import SockJS from 'sockjs-client';
import { Stomp } from '@stomp/stompjs';
const useWebSocket = () => {
const [data, setData] = useState();
useEffect(() => {
const socket = new SockJS('http://barn-backend-dns.northeurope.azurecontainer.io:8080/ws');
const stompClient = Stomp.over(socket);
stompClient.connect({}, (frame) => {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/weather', (message) => {
if (message.body) {
const parsedData = JSON.parse(message.body);
const newData = parsedData.weather;
setData(newData);
console.log('Data Received:', parsedData);
}
});
}, (err) => {
console.error('WebSocket Connection Error:', err);
});
return () => {
stompClient.disconnect(() => {
console.log('WebSocket Disconnected');
});
};
}, []);
return { data };
};
export default useWebSocket;
Questions:
Why am I getting a 400 Bad Request error when trying to connect to the WebSocket endpoint using wscat?
How can I properly test the SockJS WebSocket endpoint to ensure it is working?
Are there any specific configurations I need to add or change to make this setup work?
Additional Information:
The application is running on Azure Container Instances at
http://my-backend-dns.northeurope.azurecontainer.io:8080. When I navigate to it, I receive a “Welcome to SockJS!” message, indicating that the WebSocket endpoint is correctly set up
The WebSocket endpoint is configured with SockJS.
CORS is configured to allow requests from http://localhost:3000.
Any help would be greatly appreciated!
tried connecting to the WebSocket endpoint using wscat and my frontend application, expecting to establish a WebSocket connection. Instead, I received a “400 Bad Request” error when using wscat and no data when connecting via the frontend.
Mohamed Alhajri is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.