使用Nginx對Websocket進行反向代理

使用Nginx對Websocket進行反向代理

背景

在Vue項目中,開發websocket時,將IP和端口號固定,或者根據NODE_ENV判斷環境,修改IP和端口,相當不可取。當環境地址變更時,就需要重新打包,再發布版本,很是麻煩。使用Nginx對WebSocket進行反向代理,就會解決這一痛點問題。

Nginx配置示例

<html>
<body>
<script>
  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>
</body>
</html>

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       9001;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location ^~ /websocket {
            proxy_pass http://localhost:8090/;
            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 websocket;
            proxy_set_header 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參數可以延長這個時間。

Vue配置示例

<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:8090',
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    '^/websocket': ''
                },
            },
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章