Nginx反向代理WebSocket配置

在项目部署过程中,经常有利用Nginx将前后端代理到同一个地址的情况,但是当后端有Socket服务时,则需要一些额外的配置。

前置知识

在与WebSocket建立连接过程中,主要需要以下三个字段:

  • Upgrade:必须为websocket,表示需要升级协议为 WebSocket 进行通讯
  • Connection:必须为Upgrade,表示需要升级连接
  • Sec-WebSocket-Key:必须为随机字符串,用于握手验证,服务器也会返回一个类似的字符串

解决方法

而Nginx的默认反代配置不支持代理WebSocket,如果需要代理则需要明确地添加UpgradeConnection字段。

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    # ...
    location /websocket {
        proxy_pass http://124.222.224.186:8800;
        # important
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

其中map的语法表示,若HTTP请求头的upgrade字段为空,则将connection_upgrade变量设置为close,不为空则设置为upgrade。
注意:map语句只能写在http{}内,写在server{}内会报错

proxy_set_header表示向socket服务端传递的请求头,需要传递UpgradeConnection字段。

其他写法

如果项目无法编辑到http{},在翻阅了map的相关语法后,其实也可以利用if达到类似的效果,由于nginx中没有if-else的语法,因此用is_matched变量中转一下。

server {
    # ...
    set $is_matched 1;
    if ($http_upgrade = '') {
        set $is_matched 0;
        set $connection_upgrade close;
    }
    if ($is_matched = 1) {
        set $connection_upgrade upgrade;
    }
    location /websocket {
        proxy_pass http://124.222.224.186:8800;
        # important
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

参考文章

发布者

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注