* Closes the socket (if not already closed) and cancels all in-flight requests. * Multiple calls to this method have no additional side-effects. * @param {Function} [callback]
(callback)
| 730 | * @param {Function} [callback] |
| 731 | */ |
| 732 | close(callback) { |
| 733 | callback = callback || utils.noop; |
| 734 | |
| 735 | if (!this.connected && !this.isSocketOpen) { |
| 736 | return callback(); |
| 737 | } |
| 738 | |
| 739 | this.connected = false; |
| 740 | // Drain is never going to be emitted, once it is set to closed |
| 741 | this.removeAllListeners('drain'); |
| 742 | this.clearAndInvokePending(); |
| 743 | |
| 744 | if (!this.isSocketOpen) { |
| 745 | return callback(); |
| 746 | } |
| 747 | |
| 748 | // Set the socket as closed now (before socket.end() is called) to avoid being invoked more than once |
| 749 | this.isSocketOpen = false; |
| 750 | this.log('verbose', `Closing connection to ${this.endpointFriendlyName}`); |
| 751 | const self = this; |
| 752 | |
| 753 | // If server doesn't acknowledge the half-close within connection timeout, destroy the socket. |
| 754 | const endTimeout = setTimeout(() => { |
| 755 | this.log('info', `${this.endpointFriendlyName} did not respond to connection close within ` + |
| 756 | `${this.options.socketOptions.connectTimeout}ms, destroying connection`); |
| 757 | this.netClient.destroy(); |
| 758 | }, this.options.socketOptions.connectTimeout); |
| 759 | |
| 760 | this.netClient.once('close', function (hadError) { |
| 761 | clearTimeout(endTimeout); |
| 762 | if (hadError) { |
| 763 | self.log('info', 'The socket closed with a transmission error'); |
| 764 | } |
| 765 | setImmediate(callback); |
| 766 | }); |
| 767 | |
| 768 | // At this point, the error event can be triggered because: |
| 769 | // - It's connected and writes haven't completed yet |
| 770 | // - The server abruptly closed its end of the connection (ECONNRESET) as a result of protocol error / auth error |
| 771 | // We need to remove any listeners and make sure we callback are pending writes |
| 772 | this.netClient.removeAllListeners('error'); |
| 773 | this.netClient.on('error', err => this.clearAndInvokePending(err)); |
| 774 | |
| 775 | // Half-close the socket, it will result in 'close' event being fired |
| 776 | this.netClient.end(); |
| 777 | } |
| 778 | |
| 779 | /** |
| 780 | * Gets the local IP address to which this connection socket is bound to. |
no test coverage detected