从零搭建一个WebSocket服务到上线:用Node.js + Nginx避坑全记录(含ERR_CONNECTION_REFUSED解决方案)
2026/4/30 2:55:44 网站建设 项目流程

从零搭建WebSocket服务到上线:Node.js与Nginx实战避坑指南

第一次在本地测试WebSocket连接时,那个刺眼的ERR_CONNECTION_REFUSED错误让我愣了半天。作为全栈开发新手,我原以为按照教程把服务端和客户端代码写好就能顺利通信,现实却给了我一记闷棍。这次经历促使我完整走通了从开发到部署的WebSocket全流程,也让我深刻理解了网络通信中那些容易被忽略的细节。下面就用项目实践的方式,分享如何用Node.js+WS库搭建服务,通过Nginx反向代理,最终安全上线WebSocket服务的完整过程。

1. 本地开发环境搭建

1.1 初始化Node.js WebSocket服务

首先创建一个空目录并初始化npm项目:

mkdir websocket-demo && cd websocket-demo npm init -y npm install ws

接着创建server.js,用不到20行代码就能实现基础WebSocket服务:

const WebSocket = require('ws'); const wss = new WebSocket.Server({ port: 8080 }); wss.on('connection', (ws) => { console.log('新客户端连接'); ws.on('message', (message) => { console.log(`收到消息: ${message}`); // 广播给所有客户端 wss.clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(`服务器回复: ${message}`); } }); }); ws.send('欢迎连接WebSocket服务'); });

启动服务:

node server.js

1.2 前端连接测试页面

创建index.html测试连接:

<!DOCTYPE html> <html> <body> <script> const socket = new WebSocket('ws://localhost:8080'); socket.onopen = () => { console.log('连接成功'); socket.send('Hello Server'); }; socket.onmessage = (e) => { console.log('收到:', e.data); }; socket.onerror = (e) => { console.error('错误:', e); }; </script> </body> </html>

第一个坑:如果忘记启动服务端直接打开页面,就会遇到经典的ERR_CONNECTION_REFUSED错误。这是因为浏览器尝试连接ws://localhost:8080时,根本没有服务在监听这个端口。

2. Nginx反向代理配置

当服务需要上线时,直接暴露WebSocket端口既不安全也不符合生产环境规范。Nginx作为反向代理是更专业的方案。

2.1 关键配置参数

在Nginx配置文件中添加以下内容:

server { listen 80; server_name yourdomain.com; location /ws { proxy_pass http://localhost:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } }

核心配置说明

  • proxy_http_version 1.1:WebSocket必须使用HTTP/1.1
  • UpgradeConnection头:告知Nginx这是WebSocket连接
  • location /ws:WebSocket的访问路径

2.2 客户端连接调整

前端代码需要修改连接地址:

const socket = new WebSocket('ws://yourdomain.com/ws');

第二个坑:配置完成后如果仍然出现连接错误,可能是Nginx没有正确加载新配置。需要执行:

sudo nginx -t # 测试配置 sudo nginx -s reload # 重载配置

3. 云服务器部署实战

3.1 安全组与防火墙

在云服务商控制台,确保安全组开放了80端口(HTTP)和WebSocket服务使用的后端端口(如8080)。Ubuntu系统还需要检查UFW防火墙:

sudo ufw allow 80/tcp sudo ufw allow 8080/tcp sudo ufw enable

3.2 使用PM2持久化运行

生产环境建议使用PM2管理Node进程:

npm install pm2 -g pm2 start server.js pm2 save pm2 startup

4. 启用WSS安全连接

4.1 SSL证书配置

从Let's Encrypt获取免费证书:

sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d yourdomain.com

4.2 Nginx最终配置

server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem; location /ws { proxy_pass http://localhost:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } }

前端连接升级为WSS:

const socket = new WebSocket('wss://yourdomain.com/ws');

关键检查点

  1. 证书路径是否正确
  2. 443端口是否开放
  3. 定时更新证书(Let's Encrypt有效期90天)

5. 高级调试技巧

当遇到顽固的连接问题时,可以按以下顺序排查:

  1. 服务是否运行

    netstat -tulnp | grep 8080
  2. 端口是否可达

    telnet yourdomain.com 80
  3. 查看Nginx访问日志

    tail -f /var/log/nginx/access.log
  4. WebSocket握手过程: 在Chrome开发者工具的Network标签中,过滤WS类型请求,查看101 Switching Protocols响应

  5. 使用wscat命令行测试

    npm install -g wscat wscat -c wss://yourdomain.com/ws

6. 性能优化建议

对于生产环境,还需要考虑:

  • 心跳机制:防止连接被意外关闭

    // 服务端 setInterval(() => { wss.clients.forEach(client => { client.ping(); }); }, 30000);
  • 连接数限制:避免单机过载

    const wss = new WebSocket.Server({ port: 8080, maxPayload: 1048576, // 1MB clientTracking: true });
  • Nginx调优

    proxy_read_timeout 86400s; proxy_send_timeout 86400s; keepalive_timeout 75s;

在最近的一个实时数据监控项目中,这套配置成功支撑了500+并发WebSocket连接。最深的体会是:网络问题往往不是代码本身的问题,而是环境配置的细节决定了成败。比如有一次Nginx的proxy_read_timeout设置过短,导致长连接频繁断开,调整后才稳定运行。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询