0

I have issue on my Nodejs proxy server with socket hang up error.

Server crashes when refreshing browser on 'app.example.com'. Connection working as it should be and page is loading correctly.

I'm using http, http-proxy, cluster, domain, express, socket.io node modules.

I added code below to prevent crash, but it made every request really slow.

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

What I'm doing wrong to have this issue? I tried to add connection check on socket.io and express.io and also to proxy server with domain module without any help.

Here is some pages I readed

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

What can cause this issue?

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) }
}

These happen everytime when I refresh page on app.example.com, page loading normally and socket.io connection works normally, but somehow it crashes my proxyserver and cluster fork it up again.

Client 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

Proxy service crash

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
Community
  • 1
  • 1
EspeH
  • 1,308
  • 2
  • 16
  • 34

1 Answers1

2

✓ Found and fixed the problem

I removed this part, and socket hang up error was gone!!

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

This was documented on https://github.com/nodejitsu/node-http-proxy nodejitsu github page and I tried that node-http-proxy but changed back to http-proxy module, but forgot to remove that part out. Finally it's working.

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