基于WSS的WebSocket客户端连接报错:Initial SockJS 'Info'请求失败(404 NotFound)
从你给出的错误日志和代码来看,问题出在SockJS客户端发起的初始Info预检请求返回了404——这是SockJS协议的必经步骤:客户端会先发送一个GET请求到{你的WS URL}/info来获取服务端的SockJS配置信息,如果这个请求找不到,就会直接抛出404错误。下面是一步步的排查和解决方法:
1. 先确认服务端的SockJS端点配置是否正确
你在客户端用了SockJsClient,这意味着服务端必须对应启用SockJS支持,否则Info请求必然404。检查服务端的WebSocket配置类:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // 重点:必须调用.withSockJS()启用SockJS支持,并且端点路径要和客户端一致 registry.addEndpoint("/ws") // 这里的"/ws"要和客户端拼接的路径完全匹配 .setAllowedOrigins("*") // 根据实际业务配置允许的跨域源,测试阶段可临时放开 .withSockJS(); // 这行绝对不能少! } // 其他消息代理配置(如configureMessageBroker)... }
如果服务端没加.withSockJS(),或者端点路径不是/ws,直接就会导致Info请求找不到资源。
2. 修正客户端的WebSocket URL构建逻辑
你的代码里用了applicationUrl.replace("http", "ws") + "/ws",这里有两个潜在问题:
- 如果原
applicationUrl包含应用上下文路径(比如https://xxx/your-app),替换后要确保最终路径和服务端端点一致;如果服务端端点是根路径/ws,但你的applicationUrl带了上下文,就会导致路径错误。 - 用
replace("http", "ws")处理HTTPS时,会把https变成wss,这部分是对的,但用replaceFirst更稳妥,避免替换掉URL中其他地方的http字符串:String websocketUrl; if (applicationUrl.startsWith("https://")) { websocketUrl = applicationUrl.replaceFirst("https://", "wss://") + "/ws"; } else { websocketUrl = applicationUrl.replaceFirst("http://", "ws://") + "/ws"; }
另外,你可以手动测试服务端的Info端点:直接用浏览器或curl访问https://autoorder-is-frex-fxao-q.apps.ocp4q.bbh.com/ws/info(WSS对应的HTTPs端口),如果返回404,那100%是服务端的路径配置问题。
3. 检查服务端的部署上下文路径
从域名apps.ocp4q.bbh.com能看出你的服务部署在OpenShift/K8s环境,要确认应用的路由是否配置了正确的上下文路径。比如如果路由把/autoorder映射到你的应用,那客户端的URL应该是wss://autoorder-is-frex-fxao-q.apps.ocp4q.bbh.com/autoorder/ws,而不是直接/ws。
4. 排除跨域和SSL配置干扰
虽然错误是404,但如果服务端的跨域配置限制了源,或者SSL证书有问题,也可能导致请求被拦截伪装成404。可以先临时允许所有跨域源(setAllowedOrigins("*"))测试,同时可以先跳过SSL用WS协议连接,排除证书配置问题后再换回WSS。
最后验证步骤
- 用curl访问服务端的Info端点:
curl https://autoorder-is-frex-fxao-q.apps.ocp4q.bbh.com/ws/info,看是否返回类似{"entropy":1234,"origins":["*:*"],"cookie_needed":true,"websocket":true}的JSON响应。 - 如果返回404,回到服务端检查端点配置;如果返回200,再调试客户端的URL是否正确,或者是否有必要的请求头缺失。
内容的提问来源于stack exchange,提问作者kris82pl

