You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署AWS EC2全栈应用时Angular无法连接Node.js WebSocket问题

解决AWS EC2实例上Angular+Node.js的WebSocket连接问题

问题背景

全栈应用部署到AWS EC2实例后,后端Node.js应用运行在5000端口,前端Angular由Nginx托管在80端口,同一实例内HTTP调用正常,但WebSocket连接失败:

  • 最初客户端使用ws://localhost:5000/ws连接时,出现Connection refused错误
  • 修改为实例公网IP后,连接可建立但立即关闭,返回CloseEvent code: 1005

当前Nginx server块配置:

listen       80;
listen       [::]:80;
server_name  _;

# FRONTEND angular files
location / {
    root /my_frontend_folder_path;
}

# BACKEND node/express proxy redirects
location /api/ {
    proxy_pass http://localhost:5000/;
}

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

客户端WebSocket代码:

this.socket = new WebSocket('ws://localhost:5000/ws');
this.socket.onopen = () => {
  console.log('WebSocket connection established.');
};

分步解决方案

1. 修正客户端WebSocket连接路径

浏览器中的localhost指向用户本地机器,而非EC2实例,必须通过Nginx代理连接WebSocket服务,使用相对路径或实例域名/IP:

// 推荐:自动适配HTTP/HTTPS和域名的写法
this.socket = new WebSocket(`${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}/ws`);

// 或更简洁的相对路径(需确保前端页面部署在根路径)
this.socket = new WebSocket('/ws');

2. 优化Nginx的WebSocket代理配置

当前/ws/的proxy_pass路径可能导致后端路由匹配问题,同时添加必要的超时和缓存配置:

location /ws {
    proxy_pass http://localhost:5000/ws;  # 匹配后端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;
    # 长连接超时设置,避免WebSocket被过早断开
    proxy_connect_timeout 7d;
    proxy_send_timeout 7d;
    proxy_read_timeout 7d;
    proxy_cache_bypass $http_upgrade;  # 禁用缓存WebSocket请求
}

3. 确保Node.js后端正确处理WebSocket升级请求

以ws库为例,确保后端服务监听/ws路径并正确处理HTTP升级:

const WebSocket = require('ws');
const express = require('express');
const http = require('http');

const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ noServer: true });

// 处理HTTP升级到WebSocket
server.on('upgrade', (request, socket, head) => {
    // 验证请求路径是否为/ws
    if (request.url !== '/ws') {
        socket.destroy();
        return;
    }
    wss.handleUpgrade(request, socket, head, (ws) => {
        wss.emit('connection', ws, request);
    });
});

// 测试WebSocket连接
wss.on('connection', (ws) => {
    console.log('New WebSocket connection');
    ws.send('Connection established');
    
    ws.on('close', () => {
        console.log('WebSocket connection closed');
    });
});

server.listen(5000, () => {
    console.log('Server running on port 5000');
});

4. 检查EC2实例的安全组与内部防火墙

  • 安全组:无需开放5000端口到公网,所有请求通过Nginx的80端口代理即可
  • 内部防火墙:确保EC2实例的iptables或firewalld允许localhost到5000端口的连接(默认允许,若修改过需验证)

5. 排查CloseEvent code 1005问题

code 1005表示连接被无代码关闭,常见原因:

  • 后端WebSocket服务未监听/ws路径,导致Nginx代理的请求无法被处理
  • Nginx的proxy_pass路径配置错误,将请求转发到了后端非WebSocket路由
  • 后端未正确处理HTTP升级请求,直接关闭了连接

内容的提问来源于stack exchange,提问作者Estema

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:04:58