nginx代理配置:
http {
map $http_upgrade $connection_upgrade { //这个很重要,如果不配置,前是wss(https)时,浏览器会提示https安全问题
default upgrade;
'' close;
}
server {
...
location /websocket/ { //此为websocket路径代理地址配置
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade; //对应上面的配置,目的好像是把wss转为后端ws
proxy_send_timeout 180s; //此配置设置websocket如果空闲状态的连接时间,但此未生效
proxy_read_timeout 180s; //此配置设置websocket如果空闲状态的连接时间,但此未生效(后面还要设置)原因未查到
}
}
问题:
proxy_read_timeout在后面k8s的ingress中还要设置,直接不经过前端代理访问ingress应该地址,这个配置是生效的,目前没有查到原因,这个配置默认是1分钟,1分钟websocket会自动断连接;
解决办法:
1. 前端代码检并自动重连(此步骤不管这配置生效不生效,前端都必须有断线重连)。
2. 或者自定义实现心跳,但前端vue好像不支持websocket对应ping请求,只能发送特定的消息当做心跳,保持连接
k8s对应ingress配置:
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
......
annotations:
.....
nginx.ingress.kubernetes.io/proxy-read-timeout: '3600' #配置此两项为10分钟,此配置生效(websocket空闲10分钟断)
nginx.ingress.kubernetes.io/proxy-send-timeout: '3600' #配置此两项为10分钟,此配置生效(websocket空闲10分钟断)
spring cloud gateway配置说明:
目前我们没有配置,默认使用的是服务名转发的可能与网关版本有关。比如:ws://www.test.gateway.com/websocket/**,如果有配置网关,或网关版本,参考:
spring:
cloud:
gateway:
routes:
- id: websocket1
#uri: "ws://127.0.0.1:8081" #websocket配置,直接地址使用方式1
uri: "lb:ws://serviceName" #websocket配置,通过nacos注册中心调用serviceName使用方式2
predicates:
- Path=/websocket
vue代码简单说明(本人不是前端一点提示):
因后端没有支持SockJS所以前端代码只能用:
var url1 = "ws://www.test.gateway.com/websocket/2";
var ws1 = new WebSocket(url1);
ws1.onopen = function () {
// Web Socket 已连接上,使用 send() 方法发送数据
console.log(url2);
ws.send("测试发送");
console.log('open');
};
ws1.onmessage = function (e) {
console.log(url1+'==>message++++++++++++WebSocket::::', e.data);
};
ws1.onclose = function () {
console.log(url1+'==>close');
};
前端websocket连接方式:SockJS、WebSocket(原生)、Stompjs(试了几次没通,可自行查阅)
后端分布式websocket简单说明
后端分布式websocket代理,后期讲解,并上源码,以写为可依赖的spring-boot-stater包。
目前后端分布式websocket依照rabbitmq的消息模式实现支持:直连消息,广播消息,主题消息、延迟消息,可满足业务所有基本需求。当前依赖redis轻量完成分布式,后期可支持依赖mq,在通讯协议上打算扩展netty+grpc+(http3)这样可提供app与其它应用的通讯连接。
目前线上业务依赖此实现,目前处于稳定状态,应该用量不算具大没有测过。
实现基本原理:
分布式的难点再于:消息间的共享以为交换,使redis来即可以解决。再就是mq.当前可以完全不依赖第三方自行实现但意义不大,用java来通讯服务实现消息交换,内存+序列化都要考虑,不然对性能有要求的就会有一定影响。