Vue中如何使用 WebSocket 以及nginx代理如何配置WebSocket
# 简述websocket特性:
- 主要有ws(不加密)和wss(加密);ws是基于http请求建立握手,wss是基于https请求建立握手。
- ws的握手基于http的get方式,协议应不小于1.1。
- ws和wss的请求头会比单纯的http的请求头多很多特殊的header。
- ws请求在建立连接后,通信双方都可以在任何时刻向另一方发送数据。(http只能客户端发送请求给服务端) websocket的基本用法这里就不介绍了,网上相关的文章有很多,在此贴出不错的链接地址。 w3c对websocket的介绍:www.runoob.com/html/html5-… (opens new window)
# 项目配置
// 修改vue.config.js文件
devServer: {
open: true, // 启动后在浏览器打开
proxy: {
'/api': { // 设置普通的http代理
target: 'http://x.x.x.x:8080',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
},
'/socket': { // 设置websocket代理
target: 'http://x.x.x.x:8080',
ws: true, // 开启websocket代理 注意
changeOrigin: true,
pathRewrite: {
'^/socket': ''
}
}}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Vue单页面
export default {
data () {
return {
socket: null,
connectCount: 0, // 连接次数
heartInterval: null
}
},
created () {
this.initSocket()
},
methods: {
/**
* 建立连接是http
* 消息推送都是tcp连接,没有同源限制
* 服务端人员try catch 消息推送不成功,则关闭连接
*/
initSocket () {
const { protocol, host } = location
const url = `${protocol === 'https' ? 'wss' : 'ws'}://${host}/socket/websocket/mineStatus/${this.$store.getters.userId}`
// 判断当前浏览器是否支持WebSocket
if (typeof WebSocket === 'undefined') {
this.$notification.warning({
message: '系统提示',
description: '您的浏览器不支持socket',
duration: 4
})
return
}
this.socket = new WebSocket(url)
this.socket.onmessage = (evt) => {
if (evt.data === '连接成功' || evt.data.includes('refresh')) {
this.heartCheck() // 重置心跳检测
// this.onRefresh() 接收到推送消息,刷新列表
}
}
// 监听窗口事件,当窗口关闭时,主动断开websocket连接
window.onbeforeunload = () => {
this.closeSocket()
}
},
/**
* 定时发送心跳包
* 59s发送一次心跳,比nginx设置的最大连接时间短一点,以达到在临界点重置连接时间
*/
heartCheck () {
const _this = this
this.heartInterval && clearTimeout(this.heartInterval)
this.heartInterval = setInterval(() => {
if (this.socket.readyState === 1) { // 连接状态
this.socket.send('ping')
} else {
_this.connectCount += 1
if (_this.connectCount <= 5) {
this.initSocket() // 断点重连5次
}
}
}, 59 * 1000)
},
/** 断开websocket连接 */
closeSocket() {
this.socket.close()
this.heartInterval && clearTimeout(this.heartInterval)
}
},
destroyed() {
this.closeSocket()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
ps:当客户端网络不好,或者断网,服务器并不知情,还是会给客户端推送消息,造成资源浪费,故后端服务器要做异常处理,在消息推送不成功,主动关闭websocket连接。
# Nginx配置
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 8084;
server_name _;
root /usr/share/nginx/html/pcNet;
include /etc/nginx/default.d/*.conf;
location ^~/socket/ {
proxy_pass http://x.x.x.x:8080/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade websocket;
proxy_set_header Connection Upgrade;
}
location ^~/api/ {
proxy_pass http://x.x.x.x:8080/;
}
...
}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
配置的属性参数: proxy_pass: 要代理到的url roxy_http_version: 代理时使用的 http版本 proxy_set_header Host: http请求的主机域名 proxy_set_header X-Real-IP: 给代理设置原http请求的ip,填写$remote_addr 即可 proxy_set_header X-Forwarded-For: 反向代理之后转发之前的IP地址 proxy_set_header Upgrade: 把代理时http请求头的Upgrade 设置为原来http请求的请求头,wss协议的请求头为websocket proxy_set_header Connection: 因为代理的wss协议,所以http请求头的Connection设置为Upgrade 在此特别注意: https是加密请求,需要SSL加密,所以nginx支持https,需要配置SSL 在此贴出解决方案的链接www.cnblogs.com/zhoudawei/p… (opens new window)
链接:https://juejin.cn/post/6999844791114530852 (opens new window)
编辑 (opens new window)
上次更新: 2022/04/02, 16:35:43
- 01
- Java面试题(-)04-02
- 02
- Spring Cloud 微服务架构下的 WebSocket 解决方案04-02
- 03
- fastjson反序列化多层嵌套泛型类与java中的Type类型 转载03-02