首页 > 解决方案 > 使用 ELB 在 AWS EC2 上的套接字 IO net::ERR_CONNECTION_REFUSED

问题描述

我正在使用弹性负载均衡器在 AWS EC2 实例上运行带有 node/express 的 React 应用程序。

当我直接访问 EC2 实例时,Socket io 运行良好,但是一旦我使用 ELB url(http 或 https)访问应用程序,它就会返回 GET current url net::ERR_CONNECTION_REFUSED 每秒左右 ping 一次。

我已使用 AWS Certificate Manager 为负载均衡器创建公共证书,以便能够通过 https 访问应用程序。以下是我为 ELB 启用的侦听器:

ELB 上的监听器

在客户端,我有这样的套接字设置(与反应上下文一起使用):

let socket
const getMsg = (dispatch) => {
    if(!socket){
        socket = io(':3000', {secure: true})
        socket.on('chat msg', function(msg){
            dispatch({type:'RECEIVE_MSG', payload: msg})
        })
    }
}

const sendChat = (dispatch) => {
return async (value) => {
    socket.emit('chat msg', value)
    getMsg()
}

这是后端代码的一部分:

const app = express()

const http = require('http').createServer(app)

const io = require('socket.io')(http);

app.use(cors())
app.use(bodyParser.json())
app.use(methodOverride('_method'))

io.on('connection', socket =>{
    console.log("new connection...")
    socket.on('chat msg', async (msg) => {
        io.emit('chat msg', msg)
      });
})

const mongoUri = //hidden

mongoose.connect(mongoUri, {
    useNewUrlParser: true,
    useCreateIndex: true,
    useUnifiedTopology: true 
})
mongoose.connection.on('connected', () => {
    console.log('you are connected')
})
mongoose.connection.on('error', (err) => {
    console.log('connection error, please check your network settings')
})

http.listen(3000, ()=>{
    console.log('Listening on 3000')
})

我需要设置我的后端来接受 https 请求吗?即使我使用 https url 访问应用程序,应用程序中的其他所有内容都可以在节点/express 端使用 http 正常工作。我对快速服务器的请求的唯一问题就是socket.io。

标签: node.jsamazon-web-servicesexpressamazon-ec2socket.io

解决方案


我将在此处添加注释,因为我认为这是有价值的信息:我不久前遇到了类似的问题,在尝试支持经典 ELB 上的 Web 套接字时,您不能使用 HTTP(s) 侦听器。

相反,您可以设置 TCP SSL 终止,并将 TCP 发送到您的后端,这将允许常规的 http 和 ws 流量工作。

(此处描述:https ://www.built.io/blog/websockets-on-aws-s-elb#:~:text=AWS%20ELB%20doesn't%20support,IP%20information%20is%20not%20obtained )

否则,您可以选择支持配置的侦听器的 ALB。我认为 ALB 可能是这里的最佳选择,因为它是一种来自基础架构 POV 的“支持”解决方案。


推荐阅读