Skip to content

Commit

Permalink
Added options.closeTransport.
Browse files Browse the repository at this point in the history
The internal socket will be closed when the `unicast.Socket` is being closed.
You can change this behavior with this option.
  • Loading branch information
reklatsmasters committed Feb 13, 2018
1 parent 9ddf4c8 commit 65489c2
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
14 changes: 13 additions & 1 deletion lib/socket.js
Expand Up @@ -12,6 +12,7 @@ const pRemoteAddress = Symbol('remoteAddress')
const pRemotePort = Symbol('remotePort')
const pWritableClosed = Symbol('writableClosed')
const pReadableClosed = Symbol('readableClosed')
const pCloseTransport = Symbol('closeTransport')

/**
* This class implements stream-based dgram socket.
Expand Down Expand Up @@ -52,6 +53,8 @@ module.exports = class Socket extends Duplex {
this.once('finish', () => {
this[pWritableClosed] = true
})

this[pCloseTransport] = isBoolean(options.closeTransport) ? options.closeTransport : true
}

get remoteAddress() {
Expand Down Expand Up @@ -134,7 +137,7 @@ module.exports = class Socket extends Duplex {
}

close() {
if (!this[pSocketClosed]) {
if (!this[pSocketClosed] && this[pCloseTransport]) {
this[pSocket].close()
this[pSocketClosed] = true
}
Expand Down Expand Up @@ -179,3 +182,12 @@ function handleMessage(message, rinfo) {
this[pReadQueue].push(message)
}
}

/**
* Check if argument is boolean.
* @param {any} flag
* @returns {boolean}
*/
function isBoolean(flag) {
return typeof flag === 'boolean'
}
4 changes: 4 additions & 0 deletions readme.md
Expand Up @@ -56,6 +56,10 @@ The string representation of the local IP address. If `port` is not specified or

The string representation of the local IP address. If `address` is not specified or is `0.0.0.0`, the operating system will attempt to listen on all addresses.

* `options.closeTransport: boolean [default = true]`

The internal socket will be closed when the `unicast.Socket` is being closed. You can change this behavior with this option.

* `class Socket`

This class is an abstraction of an unicast UDP socket. A `Socket` is also a [duplex stream](https://nodejs.org/api/stream.html#stream_class_stream_duplex), so it can be both readable and writable, and it is also a [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter).
Expand Down
52 changes: 52 additions & 0 deletions test/socket.js
Expand Up @@ -199,6 +199,58 @@ test('should close when dgram socket is closed', () => {
expect(mock.close).not.toBeCalled()
})

test('should not close the socket then `closeTransport = false`', () => {
const mock = Object.assign(new Emitter(), {
send: jest.fn(),
close: jest.fn()
})

const socket = new Socket({
socket: mock,
remotePort: 1111,
remoteAddress: '127.0.0.1',
closeTransport: false
})

socket.push = jest.fn(() => true)
socket.end = jest.fn()

socket._read()
socket.close()

expect(socket.push).toHaveBeenCalledTimes(1)
expect(socket.push).toHaveBeenCalledWith(null)

expect(socket.end).toHaveBeenCalledTimes(1)
expect(mock.close).toHaveBeenCalledTimes(0)
})

test('should close the socket then `closeTransport = true`', () => {
const mock = Object.assign(new Emitter(), {
send: jest.fn(),
close: jest.fn()
})

const socket = new Socket({
socket: mock,
remotePort: 1111,
remoteAddress: '127.0.0.1',
closeTransport: true
})

socket.push = jest.fn(() => true)
socket.end = jest.fn()

socket._read()
socket.close()

expect(socket.push).toHaveBeenCalledTimes(1)
expect(socket.push).toHaveBeenCalledWith(null)

expect(socket.end).toHaveBeenCalledTimes(1)
expect(mock.close).toHaveBeenCalledTimes(1)
})

test('should free queue when socket is closed', () => {
const mock = Object.assign(new Emitter(), {
send: jest.fn(),
Expand Down

0 comments on commit 65489c2

Please sign in to comment.