如何配置Nginx以支持WebSocket?

以下是在 Nginx 中配置 WebSocket 支持的完整指南,涵盖代理设置、连接优化和常见问题排查,特别适配 Laravel 项目(如使用 Laravel Echo 或自定义 WebSocket 服务):


1. WebSocket 基础配置

在 Nginx 的 server 块中添加以下配置,确保代理 WebSocket 连接的核心参数:

server {
    listen 443 ssl;
    server_name your-domain.com;

    # SSL 配置(由 Certbot 自动生成或手动配置)
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # WebSocket 代理配置
    location /ws {
        proxy_pass http://localhost:6001;  # 指向你的 WebSocket 服务器地址
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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 86400s;  # WebSocket 长连接保持
        proxy_send_timeout 86400s;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
    }

    # Laravel 其他路由配置
    location / {
        proxy_pass http://localhost:8000;  # 指向 Laravel 应用
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

2. 关键参数说明

参数作用必需
proxy_http_version 1.1启用 HTTP/1.1 支持 WebSocket
Upgrade $http_upgrade协议升级为 WebSocket
Connection "upgrade"保持长连接
proxy_read_timeout防止空闲连接断开(建议 ≥86400s)
proxy_set_header Host传递原始域名
proxy_buffering off可选:禁用缓冲(实时性要求高时)

3. Laravel Echo Server 配置示例

如果你的 WebSocket 服务是 Laravel Echo Server(默认端口 6001),需确保:

3.1 laravel-echo-server.json 配置
{
  "authHost": "https://your-domain.com",
  "authEndpoint": "/broadcasting/auth",
  "host": "0.0.0.0",
  "port": "6001",
  "protocol": "http",
  "sslCertPath": "",
  "sslKeyPath": "",
  "socketio": {}
}
3.2 Nginx 代理广播认证路由
location /broadcasting/auth {
    proxy_pass http://localhost:8000;  # 指向 Laravel 应用
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

4. 生产环境优化

4.1 启用 SSL 直连 WebSocket
location /ws {
    proxy_pass https://localhost:6002;  # WebSocket 服务启用 SSL
    proxy_ssl_certificate /path/to/client.crt;
    proxy_ssl_certificate_key /path/to/client.key;
    # ... 其他 WebSocket 参数 ...
}
4.2 负载均衡多节点
upstream websocket_nodes {
    server ws1.example.com:6001;
    server ws2.example.com:6001;
    keepalive 64;
}

location /ws {
    proxy_pass http://websocket_nodes;
    # ... 其他 WebSocket 参数 ...
}

5. 本地开发配置(WSL2)

如果本地使用 laravel.test 域名开发,需配置自签名证书:

server {
    listen 443 ssl;
    server_name laravel.test;

    # 自签名证书路径
    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

    location /ws {
        proxy_pass http://localhost:6001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

注意:浏览器需手动信任自签名证书。


6. 测试 WebSocket 连接

6.1 使用 wscat 命令行测试
# 安装工具
npm install -g wscat

# 测试连接
wscat -c wss://your-domain.com/ws
6.2 浏览器端检查

打开开发者工具 → Network → WS 过滤,查看连接状态应为 101 Switching Protocols


7. 常见问题排查

问题 1:WebSocket 连接失败(HTTP 426)
  • 原因:Nginx 未正确传递 Upgrade
  • 解决:检查是否遗漏 proxy_set_header Upgrade $http_upgrade;
问题 2:连接频繁断开
  • 原因:Nginx 超时设置过短
  • 解决:调整 proxy_read_timeoutproxy_send_timeout
问题 3:混合内容警告(Mixed Content)
  • 原因:前端页面为 HTTPS,但 WebSocket 连接 HTTP
  • 解决:确保前端代码使用 wss:// 协议
    const socket = new WebSocket('wss://your-domain.com/ws');
    
问题 4:Laravel Echo 认证失败
  • 原因:Nginx 未正确代理 /broadcasting/auth 路由
  • 解决:检查 Laravel 路由和 Nginx 代理配置

8. 完整配置示例

Nginx + Laravel Echo Server + SSL

server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # WebSocket 路径
    location /ws {
        proxy_pass http://localhost:6001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400s;
    }

    # Laravel Echo 认证路由
    location /broadcasting/auth {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # Laravel 主应用
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

9. 性能与安全建议

  1. 启用 HTTP/2:提升多路复用性能
    listen 443 ssl http2;
    
  2. 限制 WebSocket 连接来源
    location /ws {
        allow 192.168.1.0/24;
        deny all;
        # ... 其他配置 ...
    }
    
  3. 监控连接数
    netstat -anp | grep :6001
    

通过以上配置,你的 Nginx 将完整支持 WebSocket,适配 Laravel 实时应用场景(如通知、聊天室等)。遇到问题时,优先检查 Nginx 错误日志

sudo tail -f /var/log/nginx/error.log
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值