为何客户端无法连接Spring 5 Java WebSocket服务器?
Hey there, let's figure out why you're hitting that frustrating 404 error when trying to connect to your /event-emitter WebSocket endpoint. Both JavaScript and Java clients throwing the same error tells me the root issue is almost certainly that your Spring server isn't actually mapping that path to a WebSocket handler. Here's how to fix it step by step:
1. Double-Check Your WebSocket Configuration Class
First, make sure you've properly registered the /event-emitter endpoint in your Spring config. The setup varies depending on whether you're using raw WebSocket or STOMP over WebSocket:
Raw WebSocket Config Example
If you're using plain WebSocket (no STOMP messaging), your config should look like this:
@Configuration @EnableWebSocket public class RawWebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // Register your custom handler with the /event-emitter path registry.addHandler(new CustomWebSocketHandler(), "/event-emitter") .setAllowedOrigins("*"); // Allow cross-origin for dev; restrict in production } }
STOMP Over WebSocket Config Example
If you're using STOMP (common for messaging apps), your config needs to register the STOMP endpoint explicitly:
@Configuration @EnableWebSocketMessageBroker public class StompWebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // Register the /event-emitter endpoint, with optional SockJS fallback registry.addEndpoint("/event-emitter") .setAllowedOrigins("*") .withSockJS(); // Remove this line if you don't need SockJS support } @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic", "/queue"); // Enable in-memory message broker config.setApplicationDestinationPrefixes("/app"); // Prefix for app-level message handlers } }
2. Verify the Full Endpoint Path
If your Spring app has a context path set (e.g., in application.properties as server.servlet.context-path=/my-app), your WebSocket URL must include it. For example:
- Wrong:
ws://localhost:8080/event-emitter - Correct:
ws://localhost:8080/my-app/event-emitter
Check your application.properties or application.yml for any context path configuration you might have missed.
3. Match Client Connection Code to Server Setup
Make sure your client code aligns with whether you're using raw WebSocket or STOMP with SockJS:
JavaScript Client (Raw WebSocket)
const ws = new WebSocket('ws://localhost:8080/event-emitter'); ws.onopen = () => { console.log('Successfully connected to WebSocket!'); }; ws.onerror = (error) => { console.error('WebSocket connection error:', error); };
JavaScript Client (STOMP with SockJS)
If you enabled withSockJS() in your server config, use the SockJS client library:
// Ensure you've included SockJS and STOMP libraries in your HTML first const sock = new SockJS('/event-emitter'); const stompClient = Stomp.over(sock); stompClient.connect({}, (frame) => { console.log('Connected to STOMP broker:', frame); // Add topic subscriptions here });
Java Client (Reactor Netty Example)
For your Java client, confirm the URI includes the correct path (and context path if applicable):
HttpClient client = HttpClient.create(); client.websocket() .uri("ws://localhost:8080/event-emitter") .handle((inbound, outbound) -> { // Handle WebSocket message exchange logic here return inbound.receive().then(); }) .block();
4. Check Server Startup Logs
When your Spring app starts, look for logs that confirm the WebSocket endpoint is registered. You should see an entry like this:
Mapped URL path [/event-emitter] onto handler of type [class org.springframework.web.socket.server.support.WebSocketHttpRequestHandler]
If you don't see this log, your config class isn't being picked up by Spring (e.g., it's not in a package scanned by @SpringBootApplication).
Final Notes
The 404 error is a clear sign the server doesn't recognize /event-emitter as a WebSocket endpoint. Start with verifying your config class, then check path spelling and context path, and ensure client code matches your server setup.
内容的提问来源于stack exchange,提问作者RuF

