From 7d52f867a0267692c221d978fbb086317cc24742 Mon Sep 17 00:00:00 2001 From: Martin Cizek Date: Wed, 16 Sep 2020 14:06:26 +0200 Subject: [PATCH] Client support multiple servers --- docs/client.md | 4 ++-- lib/client/client.js | 29 ++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/client.md b/docs/client.md index 3aee755..f953e59 100644 --- a/docs/client.md +++ b/docs/client.md @@ -14,7 +14,7 @@ The code to create a new client looks like: var ldap = require('ldapjs'); var client = ldap.createClient({ - url: 'ldap://127.0.0.1:1389' + url: 'ldap://127.0.0.1:1389,127.0.0.2:1389' }); You can use `ldap://` or `ldaps://`; the latter would connect over SSL (note @@ -24,7 +24,7 @@ client is: |Attribute |Description | |---------------|-----------------------------------------------------------| -|url |A valid LDAP URL (proto/host/port only) | +|url |A valid LDAP URL(s) (proto/host(s)/port(s) | |socketPath |Socket path if using AF\_UNIX sockets | |log |A compatible logger instance (Default: no-op logger) | |timeout |Milliseconds client should let operations live for before timing out (Default: Infinity)| diff --git a/lib/client/client.js b/lib/client/client.js index b254d50..45a9bee 100644 --- a/lib/client/client.js +++ b/lib/client/client.js @@ -110,12 +110,17 @@ function Client (options) { EventEmitter.call(this, options) var self = this - var _url - if (options.url) { _url = url.parse(options.url) } - this.host = _url ? _url.hostname : undefined - this.port = _url ? _url.port : false - this.secure = _url ? _url.secure : false - this.url = _url + this.servers = [] + if (options.url) { + var [, protocol, hosts, path] = options.url.match(/^([a-zA-Z]+:\/\/)([^/]*)(.*)/) + + hosts.split(',').forEach((host) => { + this.servers.push(url.parse(`${protocol}${host}${path}`)) + }) + } + + // select random server at the start + this.nextServer = Math.floor(Math.random() * this.servers.length) this.tlsOptions = options.tlsOptions this.socketPath = options.socketPath || false @@ -792,6 +797,8 @@ Client.prototype.connect = function connect () { // Establish basic socket connection function connectSocket (cb) { + self.nextServer = (self.nextServer + 1) % self.servers.length + self.url = self.servers[self.nextServer] cb = once(cb) function onResult (err, res) { @@ -820,12 +827,13 @@ Client.prototype.connect = function connect () { setupClient(cb) } - var port = (self.port || self.socketPath) + var port = (self.servers.length && self.servers[self.nextServer].port) || self.socketPath + var hostname = (self.servers.length && self.servers[self.nextServer].hostname) || undefined if (self.secure) { - socket = tls.connect(port, self.host, self.tlsOptions) + socket = tls.connect(port, hostname, self.tlsOptions) socket.once('secureConnect', onConnect) } else { - socket = net.connect(port, self.host) + socket = net.connect(port, hostname) socket.once('connect', onConnect) } socket.once('error', onResult) @@ -975,6 +983,9 @@ Client.prototype.connect = function connect () { maxDelay: this.reconnect.maxDelay }) failAfter = this.reconnect.failAfter + if (this.servers.length > 1 && failAfter) { + failAfter *= this.servers.length + } } else { retry = backoff.exponential({ initialDelay: 1,