WebSocket 握手期间出错:意外的响应代码:400 Spring boot websockets

Joh*_*nyb 4 java spring websocket spring-boot

我正在尝试实现网络套接字。我的代码:

在春季安全中,我允许带有身份验证的路径

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.csrf()
            .disable()
            .authorizeRequests()
            .antMatchers("/register","/login","/testAuth","/web","/ws").permitAll()
            .anyRequest().authenticated()
            .and()
            .exceptionHandling()
            .authenticationEntryPoint(jwtAuthenticationEntryPoint)
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
Run Code Online (Sandbox Code Playgroud)

和 ws 的配置

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {


    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new WsMessageHandler(), "/ws")
                .addInterceptors(new CustomInterceptor())
                .setAllowedOrigins("*")
                .setHandshakeHandler(new DefaultHandshakeHandler())
                .withSockJS();
    }
}
Run Code Online (Sandbox Code Playgroud)

`

  public class CustomInterceptor implements HandshakeInterceptor {
        @Override
        public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
            return true;
        }
    
        @Override
        public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, @Nullable Exception e) {
    
        }
    }
Run Code Online (Sandbox Code Playgroud)

作为客户端我使用简单的js代码:

var exampleSocket = new WebSocket("ws://localhost:8080/ws", "protocolOne");
           exampleSocket.onopen = function() {
              
              // Web Socket is connected, send data using send()
              ws.send("Message to send");
              alert("Message is sent...");
           };
Run Code Online (Sandbox Code Playgroud)

但是我收到错误:

与“ws://localhost:8080/ws”的 WebSocket 连接失败:WebSocket 握手期间出错:意外的响应代码:400

是什么原因造成的?一切都应该是正确的。感谢您的回答

jac*_*neo 10

我发现你的代码有一些错误:

  1. 如果使用 WebSocket() 作为客户端,则应在 WebSocketConfig 中注释 withSocktJS()。并喜欢它
@Configuration
@EnableWebSocket
public class WebSocketConfig2 implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new WsMessageHandler(), "/ws")
                .addInterceptors(new CustomInterceptor())
                .setAllowedOrigins("*")
                .setHandshakeHandler(new DefaultHandshakeHandler())
//                .withSockJS()
        ;
    }
}

Run Code Online (Sandbox Code Playgroud)
  1. 你的客户端js代码是错误的。没有ws。您应该使用 exampleSocket 来发送。像下面这样
                var exampleSocket = new WebSocket("ws://localhost:8081/ws", "protocolOne");
                exampleSocket.onopen = function(ws) {
                    console.log('-----------------', ws);
                    // Web Socket is connected, send data using send()
                    exampleSocket.send("Message to send");
                    alert("Message is sent...");
                };

Run Code Online (Sandbox Code Playgroud)
  1. 在客户端发送 websocket 时,您指向一个名为“protocolOne”的协议,您应该在 CustomInterceptor 中将其返回。您可以按如下操作。
public class CustomInterceptor implements HandshakeInterceptor {
    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, @Nullable Exception e) {
        if(serverHttpRequest.getHeaders() == null )
            return ;
        if(serverHttpRequest.getHeaders().get("Sec-WebSocket-Protocol") == null)
            return ;
        String protocol = (String) serverHttpRequest.getHeaders().get("Sec-WebSocket-Protocol").get(0);
        if(protocol == null)
            return ;

        serverHttpResponse.getHeaders().add("Sec-WebSocket-Protocol", protocol);

    }

}

Run Code Online (Sandbox Code Playgroud)