使用Nginx对Websocket进行反向代理
背景
Nginx配置示例
Vue配置示例
背景
在Vue项目中,开发websocket时,将IP和端口号固定,或者根据NODE_ENV判断环境,修改IP和端口,相当不可取。当环境地址变更时,就需要重新打包,再发布版本,很是麻烦。使用Nginx对WebSocket进行反向代理,就会解决这一痛点问题。Nginx从1.3.13版本开始支持对Websocket进行反向代理。
Nginx配置示例
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location ^~ /websocket {
proxy_pass http://localhost: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_read_timeout 120s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
}
关键配置说明
map $http_upgrade $connection_upgrade {
default upgrade;
‘’ close;
}
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
以上配置的作用是在HTTP请求中增加头部
Upgrade: websocket
Connection: Upgrade
默认情况下,连接将会在无数据传输60秒后关闭,proxy_read_timeout参数可以延长这个时间。
<template>
<div class="home">
</div>
</template>
<script>
export default {
name: 'home',
created () {
this.init()
},
methods: {
init () {
let wsServer = `${location.protocol === 'https' ? 'wss' : 'ws'}://${location.host}/websocket/order`
let websocket = new WebSocket(wsServer)
websocket.onopen = function (evt) { onOpen(evt) }
websocket.onclose = function (evt) { onClose(evt) }
websocket.onmessage = function (evt) { onMessage(evt) }
websocket.onerror = function (evt) { onError(evt) }
function onOpen (evt) {
console.log('Connected to WebSocket server.')
}
function onClose (evt) {
console.log('Disconnected')
}
function onMessage (evt) {
console.log('Retrieved data from server: ' + evt.data)
}
function onError (evt) {
console.log('Error occured: ' + evt.data)
}
}
}
}
</script>vue.config.js
配置
module.exports = {
devServer: {
proxy: {
'/websocket': {
target: 'http://localhost:8080',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/websocket': ''
},
},
}
}
}