offer a new port and listen

This commit is contained in:
Ricardo Gobbo de Souza 2018-11-27 20:52:04 -02:00
parent 96df3176e5
commit 22a4f60bde
3 changed files with 61 additions and 14 deletions

View File

@ -19,6 +19,7 @@
"etag": "^1.8.1",
"fresh": "^0.5.2",
"fs-extra": "^7.0.1",
"get-port": "^4.0.0",
"ip": "^1.1.5",
"launch-editor-middleware": "^2.2.1",
"pify": "^4.0.1",

View File

@ -4,6 +4,7 @@ import enableDestroy from 'server-destroy'
import ip from 'ip'
import consola from 'consola'
import pify from 'pify'
import getPort from 'get-port'
export default class Listener {
constructor({ port, host, socket, https, app }) {
@ -55,16 +56,10 @@ export default class Listener {
this._server = protocol.createServer.apply(protocol, protocolOpts.concat(this.app))
// Listen server error
this._server.on('error', this.errorHandler)
// Prepare listenArgs
const listenArgs = this.socket ? { path: this.socket } : { host: this.host, port: this.port }
listenArgs.exclusive = false
this._server.on('error', this.serverErrorHandler.bind(this))
// Call server.listen
this.server = await new Promise((resolve, reject) => {
const s = this._server.listen(listenArgs, error => error ? reject(error) : resolve(s))
})
await this.serverListen()
// Enable destroy support
enableDestroy(this.server)
@ -76,13 +71,29 @@ export default class Listener {
this.listening = true
}
errorHandler(e) {
const errors = {
EACCES: 'Permission denied. Does your user have permission?',
EADDRINUSE: `Address \`${this.host}:${this.port}\` is already in use. Do you run another service on the same port?`,
EDQUOT: 'Disk quota exceeded. Do you have space in disk?'
async serverErrorHandler(e) {
if(e.code === 'EADDRINUSE') {
consola.warn(`Address \`${this.host}:${this.port}\` is already in use.`)
this._server.close()
this.port = await getPort()
await this.serverListen()
return
}
consola.error(errors[e.code] || e)
consola.error(e)
}
async serverListen() {
// Prepare listenArgs
const listenArgs = this.socket ? { path: this.socket } : { host: this.host, port: this.port }
listenArgs.exclusive = false
// Call server.listen
this.server = await new Promise((resolve, reject) => {
const s = this._server.listen(listenArgs, error => error ? reject(error) : resolve(s))
})
}
}

View File

@ -0,0 +1,35 @@
import consola from 'consola'
import { loadFixture, getPort, Nuxt } from '../utils'
let port = null
let nuxt1 = null
let nuxt2 = null
describe('server listen', () => {
beforeAll(async () => {
const config = await loadFixture('empty')
nuxt1 = new Nuxt(config)
nuxt2 = new Nuxt(config)
port = await getPort()
})
test('should listen different ports', async () => {
await nuxt1.server.listen(port, 'localhost')
await nuxt2.server.listen(port, 'localhost')
const host = nuxt1.server.listeners[0].host
const port1 = nuxt1.server.listeners[0].port
const port2 = nuxt2.server.listeners[0].port
expect(port1).toBe(port)
expect(port2).not.toBe(port1)
expect(consola.warn).toHaveBeenCalledTimes(1)
expect(consola.warn).toHaveBeenCalledWith(`Address \`${host}:${port}\` is already in use.`)
})
afterAll(async () => {
await nuxt1.close()
await nuxt2.close()
})
})