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", "etag": "^1.8.1",
"fresh": "^0.5.2", "fresh": "^0.5.2",
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",
"get-port": "^4.0.0",
"ip": "^1.1.5", "ip": "^1.1.5",
"launch-editor-middleware": "^2.2.1", "launch-editor-middleware": "^2.2.1",
"pify": "^4.0.1", "pify": "^4.0.1",

View File

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