Error during WebSocket handshake: Sent non-empty ‘Sec-WebSocket-Protocol’ header but no response was received
分析
和前端同事调试WebSocket接口,一次性通过,作为一个老码农很是欣慰。
第二天另外一个前端同事拉取代码,跑项目。啊,怎么WebSokcet连不上,一堆报错。
我看了后台在连接后立马报错,然后又断开连接。丈二和尚摸不着头脑。
通过在线网站多次测试WebSocket连接,没复现,这不是没问题嘛。
网站地址: http://websocket.jsonin.com/
通过我4年开发,6年工作经验来看,一定是前端的问题,一定是别人的问题,与我无关。继续搬砖…
又过了一会,看着后台无休止的报错,烦死了,让我来终结这一切吧。
前端同事发来的错误信息:Error during WebSocket handshake: Sent non-empty ‘Sec-WebSocket-Protocol’ header but no response was received
WebSocket握手时出错:发送了非空的’Sec-WebSocket-Protocol’报头,但没有收到响应。
原来小丑是我自己,真是后端的问题,没有给前端响应头。
分析原因:应该是前端传了非空的’Sec-WebSocket-Protocol’请求头,后端没有给响应,火狐可以是因为火狐没有传,谷歌又传了这个值,害,真麻烦。
初步解决
知道问题了那就先解决,首先想到的是给HttpServletReponse返回请求头Sec-WebSocket-Protocol的数据。有一说一,开干。
问题又来了,我从哪里获取HttpServletReponse呢,索性给加了两个参数,启动报错,人家不识别。。。
看了一下这个注解,有个配置参数,就你了。写个配置类,在返回的头上加上参数。
配置类如下:
最终解决
完事,问了下报错的前端同事可以了不,不出所料,确实可以了。OK,继续干活了。
回头发现控制台又报错,并且通过网站测试WebSokcet也连不上了。。。完蛋,治好了咽炎,鼻炎又犯了。
谷歌浏览器是可以了,但是火狐浏览器连接不到,那问题就明朗了,火狐没有传Sec-WebSocket-Protocol,而谷歌浏览器传这个值了。加个判断最终解决。
package com.system.graphical.common.websocket;
import org.springframework.stereotype.Component;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
import java.util.List;
@Component
public class WebSocketConfig extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
List<String> list = request.getHeaders().get("Sec-WebSocket-Protocol");
if (list != null && list.size() > 0) {
response.getHeaders().put("Sec-WebSocket-Protocol", list);
super.modifyHandshake(sec, request, response);
}
}
}