(转) websocket + Nginx 部署后报错:404
前言
最近项目中有端对端通信场景,实时性要求较高,考虑后选用了websocket 这一通信协议,本地做了个demo测试,跑的好好的,部署到测试服务器上,出现了客户端连接服务端时提示404的问题,下面来看下。
正文
问题描述
本地客户端程序简单写了个html,连接到服务端成功后的页面如下
将服务端代码部署到测试服务器上,想跟另一端做联调测试,部署完后,本地客户端再次连接,显示异常:
看浏览器控制台报错如下:
WebSocket connection to 'ws://ip:port/temperature/productWebSocket/9006' failed: Error during WebSocket handshake: Unexpected response code: 404
解决方法
修改服务器上nginx.conf 如下:
location /temperature{ proxy_pass http://127.0.0.1:port/temperature; # 增加Upgrade协议头和Connection协议头,使http连接升级到websocket连接 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
原因分析
我们都知道http协议使无状态的,而websocket协议是建立一个tcp 长链接,而websocket协议的握手和http 是兼容的,它使用http 的Upgrade协议头将Http 连接升级到WebSocket连接,这个特性使得websocket应用程序可以很容易地应用到现有的基础设施。
大家可以看下http 和 websocket 通信协议在浏览器上的不同:
Http协议:
WebSocket协议:
WebSocket协议的握手和HTTP是兼容的,它使用HTTP的Upgrade协议头将连接从HTTP连接升级到WebSocket连接。这个特性使得WebSocket应用程序可以很容易地应用到现有的基础设施。
HTTP的Upgrade协议头机制用于将连接从HTTP连接升级为WebSocket连接,Upgrade机制使用了Upgrade协议头和Connection协议头。反向代理服务器在支持WebSocket协议方面面临着一些挑战。挑战之一是WebSocket是一个逐段转发(hop-by-hop)协议,因此当代理服务器拦截到来自客户端的Upgrade请求时,代理服务器需要将自己的Upgrade请求发送给后端服务器,包括合适的请求头。而且,由于WebSocket连接是长连接,与传统的HTTP端连接截然不同,故反向代理服务器还需要允许将这些连接处于打开状态,而不能因为其空闲就关闭了连接。
参考链接
https://www.jb51.net/article/59847.htm