使用nginx代理websocket
在nginx配置文件中配置:
http{
.....
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
#旧版
server{
listen 443;
ssl on;
ssl_certificate /etc/nginx/cert/ssl.crt;
ssl_certificate_key /etc/nginx/cert/ssl.key;
root /usr/local;
location /socket {
proxy_pass https://sign.xxxxxx.cn:8989/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
#新版
server{
listen 443ssl;
ssl_certificate /etc/nginx/cert/ssl.crt;
ssl_certificate_key /etc/nginx/cert/ssl.key;
root /usr/local;
location /socket {
proxy_pass https://sign.xxxxxx.cn:8989/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
.....
}
当websocket被nginx代理后,默认的连接时长为60秒,以vue为例:
data () {
return {
audioUrl: window.SITE_CONFIG.version + '/static/audio/test.wav',
lockReconnect: false, // 是否真正建立连接
timeout: 28 * 1000, // 30秒一次心跳
timeoutObj: null, // 心跳心跳倒计时
serverTimeoutObj: null, // 心跳倒计时
timeoutnum: null, // 断开 重连倒计时
lastRunTime: Date.now(), // 上次播放声音的时间
loading: true
}
},
methods: {
init () {
console.log(this.userId)
if (typeof (WebSocket) === 'undefined') {
alert('您的浏览器不支持websocket')
} else {
this.webSocket = new WebSocket('wss://域名/**/websocket/' + this.userId)
this.webSocket.onopen = this.webSocketOpen
this.webSocket.onerror = this.webSocketError
this.webSocket.onmessage = this.webSocketGetMessage
this.webSocket.onclose = this.webSocketClose
}
},
webSocketOpen () {
// console.log('socket连接成功')
this.start() // 开启心跳
},
webSocketError () {
console.log('socket连接错误')
this.reconnect()
},
webSocketGetMessage (msg) {
if (JSON.parse(msg.data).messageType === 5) {
this.playAudio()
}
if (JSON.parse(msg.data).messageType === 1) {
console.log('心跳检测')
this.reset()
}
},
webSocketClose () {
console.log('socket已关闭')
},
destroyed () {
this.webSocket.onclose = this.webSocketClose
},
playAudio () {
const audio = document.getElementById('audio')
audio.play()
console.log('播放成功')
},
start () { // 开启心跳
var self = this
self.timeoutObj && clearTimeout(self.timeoutObj)
self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj)
self.timeoutObj = setTimeout(function () {
// 这里发送一个心跳,后端收到后,返回一个心跳消息,
if (self.webSocket.readyState === 1) { // 如果连接正常
self.webSocket.send('heartCheck')
} else { // 否则重连
self.reconnect()
}
self.serverTimeoutObj = setTimeout(function () {
// 超时关闭
console.log('超时了')
self.webSocket.close()
}, self.timeout)
}, self.timeout)
},
reconnect () { // 重新连接
var that = this
if (that.lockReconnect) {
return
};
that.lockReconnect = true
// 没连接上会一直重连,设置延迟避免请求过多
that.timeoutnum && clearTimeout(that.timeoutnum)
that.timeoutnum = setTimeout(function () {
// 新连接
that.init()
that.lockReconnect = false
}, 5000)
},
reset () { // 重置心跳
var that = this
// 清除时间
clearTimeout(that.timeoutObj)
clearTimeout(that.serverTimeoutObj)
// 重启心跳
that.start()
}
}