Stomp以wss方式连接websocket
一、问题描述
项目中遇到使用stomp连接websocket,当使用ws://ip:port/ws协议来连接时没有问题,但是放到服务器上却报如下错误:
Mixed Content: The page at ‘https://ip:port/‘ was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint ‘ws://{ip}:{port}/‘.
This request has been blocked; this endpoint must be available over WSS.
Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
二、解决方案
2.1 nginx配置
chrome浏览器报这个意思就是说在https访问的域下不能使用非ssl加密的连接,查看websocket协议为ws,那肯定不支持。
由于我的服务是通过nginx代理成https的,所以在网上找了一圈,最简单的解决方案也是在nginx里边代理ws协议为wss。具体配置如下:
location /ws {
proxy_pass http://ip:15674;
proxy_read_timeout 60s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
nginx关于websocket的配置说明:
自1.3 版本开始,Nginx就支持 WebSocket,并且可以为 WebSocket 应用程序做反向代理和负载均衡。WebSocket 和 HTTP 是两种不同的协议,但是 WebSocket 中的握手和 HTTP 中的握手兼容,它使用 HTTP 中的 Upgrade 协议头将连接从 HTTP 升级到 WebSocket,当客户端发过来一个 Connection: Upgrade请求头时,其实Nginx是不知道的。所以,当 Nginx 代理服务器拦截到一个客户端发来的 Upgrade 请求时,需要我们显式的配置Connection、Upgrade头信息,并使用 101(交换协议)返回响应,在客户端、代理服务器和后端应用服务之间建立隧道来支持 WebSocket。
2.2前端配置
前端stomp连接websocket的代码如下:
this.client= Stomp.client("wss://{ip/域名}/ws")
const headers = {
'login': 'xxxx',
'passcode': 'xxxx',
'host': '/'
}
//创建连接,放入连接成功和失败回调函数
this.client.connect(headers, this.onConnected, this.onFailed);