Nodejs http-proxy 服务器在 socket.io 连接时崩溃

Nodejs http-proxy server crash on socket.io connection

我的 Nodejs 代理服务器 有问题套接字挂起错误

在 'app.example.com' 上刷新浏览器时服务器崩溃。连接正常工作,页面加载正确。

我正在使用 httphttp-proxyclusterdomain, express, socket.io node modules.

我在下面添加了代码以防止崩溃,但它使每个请求非常慢

process.on('uncaughtException', err => { console.log('Uncaught Exception', err)}

出现这个问题是我做错了什么?我试图在 socket.io 和 express.io 上添加连接检查,并且在没有任何帮助的情况下也添加到带有域模块的代理服务器。

这是我读过的一些页面

http://www.clock.co.uk/blog/preventing-http-raise-hangup-error-on-destroyed-socket-write-from-crashing-your-nodejs-server

How to debug a socket hang up error in NodeJS?

Socket.IO server hangs up

"Error: socket hang up" with Express

什么会导致此问题?

proxy_server.js

const http = require('http'),
      httpProxy = require('http-proxy'),
      domain = require('domain'),
      cluster = require('cluster'),
      numCpus = require('os').cpus().length

if(cluster.isMaster) {
    for(let i = 0;i < numCpus;i++) {
        cluster.fork()
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`Worker ${worker.process.pid} closed at ${new Date()}\nRestarting`)
        cluster.fork()
    })
} else {

    const server = http.createServer((req, res) => {
        let host = req.headers.host

        let reqd = domain.create()
        reqd.add(req)
        reqd.add(res)

        // On error dispose of the domain
        reqd.on('error', err => {
            console.log('Error', err, req.url)
            reqd.dispose()
        })

        let proxy = new httpProxy.createProxy({
            target: 'localhost'
        })

        let subdomain = host.split('.')[0]
        switch(subdomain) {
            case 'app':
                proxy.web(req, res, { target: 'http://localhost:3010' }, err => {  } )
                break
            default:
                proxy.web(req, res, { target: 'http://localhost:3000' }, err => {  } )
                break
        }
    }

    server.listen(80)
    server.on('upgrade', (req, socket, head) => {
        proxy.ws(req, socket, head)
    })
}

app.js

const express = require('express'),
      app = express()
      io = require('socket.io')(app),

app.use((req, res, next) => {
    req.socket.on('error', () => {
        console.log('Error on req socket')
    })
    res.socket.on('error', () => {
        console.log('Error on res socket')
    })
    next()
})

... my application configs ...

io.on('connection', socket => {
    if(socket.connected)
        socket.emit('connected', { response: { success: true } })
})

app.listen(3010)

client.js

$(document).ready(() => {
    let socket = io.connect('app.example.com')

    socket.on('connected', () => { console.log('✓ Socket connected!') }
    socket.on('disconnect', () => { console.log(' Socket disconnected!') }
    socket.on('error', (err) => { console.log(' Socket error!\n', err) }
}

每当我在 app.example.com 上刷新页面时,这些都会发生,页面加载正常并且 socket.io 连接正常,但不知何故它使我的代理服务器和集群再次分叉。

客户端console.log

✓ Socket connected!

WebSocket connection to 'ws://app.example.com/socket.io/?EIO=3&transport=websocket&sid=sRs29QgeORgPFiIKAAAC' failed: Connection closed before receiving a handshake response

代理服务崩溃

Error: socket hang up
    at createHangUpError (_http_client.js:250:15)
    at Socket.socketOnEnd (_http_client.js:342:23)
    at emitNone (events.js:91:20)
    at Socket.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:926:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickDomainCallback (internal/process/next_tick.js:122:9)

Worker 2208 closed at Wed May 11 2016 18:08:39 GMT+0300 (EEST)
Restarting
Worker 7153 started succesfully

✓ 找到并解决了问题

我删除了这部分,套接字挂起错误消失了!!

server.on('upgrade', (req, socket, head) => {
    proxy.ws(req, socket, head)
})

这在 https://github.com/nodejitsu/node-http-proxy nodejitsu github 页面上有记录,我尝试了那个 node-http-proxy 但改回了 http-proxy 模块,但忘了删除那部分。终于成功了。

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
   proxy.ws(req, socket, head);
});