| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent e40cee5 commit a534b65
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3707,7 +3707,7 @@ changes: | |||
| 3707 | 3707 | **Default:** `false`. | |
| 3708 | 3708 | * `keepAlive` {boolean} If set to `true`, it enables keep-alive functionality | |
| 3709 | 3709 | on the socket immediately after a new incoming connection is received, | |
| 3710 | - similarly on what is done in \[`socket.setKeepAlive([enable][, initialDelay])`]\[`socket.setKeepAlive(enable, initialDelay)`]. | ||
| 3710 | + similarly on what is done in [`socket.setKeepAlive()`][]. | ||
| 3711 | 3711 | **Default:** `false`. | |
| 3712 | 3712 | * `keepAliveInitialDelay` {number} If set to a positive number, it sets the | |
| 3713 | 3713 | initial delay before the first keepalive probe is sent on an idle socket. | |
@@ -4707,7 +4707,7 @@ const agent2 = new http.Agent({ proxyEnv: process.env }); | |||
| 4707 | 4707 | [`server.timeout`]: #servertimeout | |
| 4708 | 4708 | [`setHeader(name, value)`]: #requestsetheadername-value | |
| 4709 | 4709 | [`socket.connect()`]: net.md#socketconnectoptions-connectlistener | |
| 4710 | - [`socket.setKeepAlive()`]: net.md#socketsetkeepaliveenable-initialdelay | ||
| 4710 | + [`socket.setKeepAlive()`]: net.md#socketsetkeepalive | ||
| 4711 | 4711 | [`socket.setNoDelay()`]: net.md#socketsetnodelaynodelay | |
| 4712 | 4712 | [`socket.setTimeout()`]: net.md#socketsettimeouttimeout-callback | |
| 4713 | 4713 | [`socket.unref()`]: net.md#socketunref | |
@@ -4719,4 +4719,4 @@ const agent2 = new http.Agent({ proxyEnv: process.env }); | |||
| 4719 | 4719 | [`writable.uncork()`]: stream.md#writableuncork | |
| 4720 | 4720 | [`writable.write()`]: stream.md#writablewritechunk-encoding-callback | |
| 4721 | 4721 | [information event]: #event-information | |
| 4722 | - [initial delay]: net.md#socketsetkeepaliveenable-initialdelay | ||
| 4722 | + [initial delay]: net.md#socketsetkeepaliveenable-initialdelay-interval-count | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1374,11 +1374,76 @@ added: v0.1.90 | |||
| 1374 | 1374 | Set the encoding for the socket as a [Readable Stream][]. See | |
| 1375 | 1375 | [`readable.setEncoding()`][] for more information. | |
| 1376 | 1376 | ||
| 1377 | - ### `socket.setKeepAlive([enable][, initialDelay])` | ||
| 1377 | + ### `socket.setKeepAlive()` | ||
| 1378 | + | ||
| 1379 | + Enable/disable keep-alive functionality, and optionally configure the | ||
| 1380 | + keepalive probe timing. Returns the socket itself. | ||
| 1381 | + | ||
| 1382 | + Possible signatures: | ||
| 1383 | + | ||
| 1384 | + * [`socket.setKeepAlive([options])`][`socket.setKeepAlive(options)`] | ||
| 1385 | + * [`socket.setKeepAlive([enable][, initialDelay][, interval][, count])`][`socket.setKeepAlive(enable)`] | ||
| 1386 | + | ||
| 1387 | + Enabling keep-alive sets the initial delay before the first keepalive probe is | ||
| 1388 | + sent on an idle socket. | ||
| 1389 | + | ||
| 1390 | + Set `initialDelay` (in milliseconds) to set the delay between the last | ||
| 1391 | + data packet received and the first keepalive probe. Setting `0` for | ||
| 1392 | + `initialDelay` will leave the value unchanged from the default | ||
| 1393 | + (or previous) setting. | ||
| 1394 | + | ||
| 1395 | + Set `interval` (in milliseconds) to set the delay between successive | ||
| 1396 | + keepalive probes once they begin (`TCP_KEEPINTVL`). Set `count` to the | ||
| 1397 | + number of unacknowledged probes sent before the connection is dropped | ||
| 1398 | + (`TCP_KEEPCNT`). Both are only applied when keep-alive is enabled. | ||
| 1399 | + Omitting `interval` or `count` uses the defaults of `1000` ms and `10`. | ||
| 1400 | + As with `initialDelay`, a non-positive `interval` or `count` leaves the | ||
| 1401 | + corresponding system default unchanged. | ||
| 1402 | + | ||
| 1403 | + `initialDelay` and `interval` are specified in milliseconds but the | ||
| 1404 | + underlying socket options are configured in whole seconds; the values are | ||
| 1405 | + divided by `1000` and rounded down before being applied. | ||
| 1406 | + | ||
| 1407 | + Enabling the keep-alive functionality will set the following socket options: | ||
| 1408 | + | ||
| 1409 | + * `SO_KEEPALIVE=1` | ||
| 1410 | + * `TCP_KEEPIDLE=initialDelay / 1000` | ||
| 1411 | + * `TCP_KEEPCNT=count` | ||
| 1412 | + * `TCP_KEEPINTVL=interval / 1000` | ||
| 1413 | + | ||
| 1414 | + On Windows versions older than build 1709, keep-alive is configured through | ||
| 1415 | + `SIO_KEEPALIVE_VALS`, which has no probe-count field, so `count` is ignored on | ||
| 1416 | + those platforms. | ||
| 1417 | + | ||
| 1418 | + #### `socket.setKeepAlive([options])` | ||
| 1419 | + | ||
| 1420 | + <!-- YAML | ||
| 1421 | + added: REPLACEME | ||
| 1422 | + --> | ||
| 1423 | + | ||
| 1424 | + * `options` {Object} | ||
| 1425 | + * `enable` {boolean} **Default:** `false` | ||
| 1426 | + * `initialDelay` {number} **Default:** `0` | ||
| 1427 | + * `interval` {number} **Default:** `1000` | ||
| 1428 | + * `count` {number} **Default:** `10` | ||
| 1429 | + * Returns: {net.Socket} The socket itself. | ||
| 1430 | + | ||
| 1431 | + Configure keep-alive using an options object. See [`socket.setKeepAlive()`][] | ||
| 1432 | + for a description of each property. | ||
| 1433 | + | ||
| 1434 | + ```js | ||
| 1435 | + socket.setKeepAlive({ enable: true, initialDelay: 1000, interval: 1000, count: 10 }); | ||
| 1436 | + ``` | ||
| 1437 | + | ||
| 1438 | + #### `socket.setKeepAlive([enable][, initialDelay][, interval][, count])` | ||
| 1378 | 1439 | ||
| 1379 | 1440 | <!-- YAML | |
| 1380 | 1441 | added: v0.1.92 | |
| 1381 | 1442 | changes: | |
| 1443 | + - version: REPLACEME | ||
| 1444 | + pr-url: https://github.com/nodejs/node/pull/63825 | ||
| 1445 | + description: Added the `interval` and `count` arguments to configure | ||
| 1446 | + `TCP_KEEPINTVL` and `TCP_KEEPCNT`. | ||
| 1382 | 1447 | - version: | |
| 1383 | 1448 | - v13.12.0 | |
| 1384 | 1449 | - v12.17.0 | |
@@ -1388,22 +1453,12 @@ changes: | |||
| 1388 | 1453 | ||
| 1389 | 1454 | * `enable` {boolean} **Default:** `false` | |
| 1390 | 1455 | * `initialDelay` {number} **Default:** `0` | |
| 1456 | + * `interval` {number} **Default:** `1000` | ||
| 1457 | + * `count` {number} **Default:** `10` | ||
| 1391 | 1458 | * Returns: {net.Socket} The socket itself. | |
| 1392 | 1459 | ||
| 1393 | - Enable/disable keep-alive functionality, and optionally set the initial | ||
| 1394 | - delay before the first keepalive probe is sent on an idle socket. | ||
| 1395 | - | ||
| 1396 | - Set `initialDelay` (in milliseconds) to set the delay between the last | ||
| 1397 | - data packet received and the first keepalive probe. Setting `0` for | ||
| 1398 | - `initialDelay` will leave the value unchanged from the default | ||
| 1399 | - (or previous) setting. | ||
| 1400 | - | ||
| 1401 | - Enabling the keep-alive functionality will set the following socket options: | ||
| 1402 | - | ||
| 1403 | - * `SO_KEEPALIVE=1` | ||
| 1404 | - * `TCP_KEEPIDLE=initialDelay` | ||
| 1405 | - * `TCP_KEEPCNT=10` | ||
| 1406 | - * `TCP_KEEPINTVL=1` | ||
| 1460 | + Configure keep-alive using positional arguments. See | ||
| 1461 | + [`socket.setKeepAlive()`][] for a description of each argument. | ||
| 1407 | 1462 | ||
| 1408 | 1463 | ### `socket.setNoDelay([noDelay])` | |
| 1409 | 1464 | ||
@@ -2070,7 +2125,9 @@ net.isIPv6('fhqwhgads'); // returns false | |||
| 2070 | 2125 | [`socket.pause()`]: #socketpause | |
| 2071 | 2126 | [`socket.resume()`]: #socketresume | |
| 2072 | 2127 | [`socket.setEncoding()`]: #socketsetencodingencoding | |
| 2073 | - [`socket.setKeepAlive()`]: #socketsetkeepaliveenable-initialdelay | ||
| 2128 | + [`socket.setKeepAlive()`]: #socketsetkeepalive | ||
| 2129 | + [`socket.setKeepAlive(enable)`]: #socketsetkeepaliveenable-initialdelay-interval-count | ||
| 2130 | + [`socket.setKeepAlive(options)`]: #socketsetkeepaliveoptions | ||
| 2074 | 2131 | [`socket.setTimeout()`]: #socketsettimeouttimeout-callback | |
| 2075 | 2132 | [`socket.setTimeout(timeout)`]: #socketsettimeouttimeout-callback | |
| 2076 | 2133 | [`stream.getDefaultHighWaterMark()`]: stream.md#streamgetdefaulthighwatermarkobjectmode | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -103,6 +103,8 @@ module.exports = { | |||
| 103 | 103 | kSetNoDelay: Symbol('kSetNoDelay'), | |
| 104 | 104 | kSetKeepAlive: Symbol('kSetKeepAlive'), | |
| 105 | 105 | kSetKeepAliveInitialDelay: Symbol('kSetKeepAliveInitialDelay'), | |
| 106 | + kSetKeepAliveInterval: Symbol('kSetKeepAliveInterval'), | ||
| 107 | + kSetKeepAliveCount: Symbol('kSetKeepAliveCount'), | ||
| 106 | 108 | isIP, | |
| 107 | 109 | isIPv4, | |
| 108 | 110 | isIPv6, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -51,6 +51,8 @@ const { | |||
| 51 | 51 | kSetNoDelay, | |
| 52 | 52 | kSetKeepAlive, | |
| 53 | 53 | kSetKeepAliveInitialDelay, | |
| 54 | + kSetKeepAliveInterval, | ||
| 55 | + kSetKeepAliveCount, | ||
| 54 | 56 | isIP, | |
| 55 | 57 | isIPv4, | |
| 56 | 58 | isIPv6, | |
@@ -630,13 +632,25 @@ Socket.prototype.setNoDelay = function(enable) { | |||
| 630 | 632 | }; | |
| 631 | 633 | ||
| 632 | 634 | ||
| 633 | - Socket.prototype.setKeepAlive = function(enable, initialDelayMsecs) { | ||
| 635 | + Socket.prototype.setKeepAlive = function(enable, initialDelayMsecs, | ||
| 636 | + intervalMsecs, count) { | ||
| 637 | + if (enable !== null && typeof enable === 'object') { | ||
| 638 | + const options = enable; | ||
| 639 | + enable = options.enable; | ||
| 640 | + initialDelayMsecs = options.initialDelay; | ||
| 641 | + intervalMsecs = options.interval; | ||
| 642 | + count = options.count; | ||
| 643 | + } | ||
| 634 | 644 | enable = Boolean(enable); | |
| 635 | 645 | const initialDelay = ~~(initialDelayMsecs / 1000); | |
| 646 | + const interval = intervalMsecs === undefined ? | ||
| 647 | + undefined : ~~(intervalMsecs / 1000); | ||
| 636 | 648 | ||
| 637 | 649 | if (!this._handle) { | |
| 638 | 650 | this[kSetKeepAlive] = enable; | |
| 639 | 651 | this[kSetKeepAliveInitialDelay] = initialDelay; | |
| 652 | + this[kSetKeepAliveInterval] = interval; | ||
| 653 | + this[kSetKeepAliveCount] = count; | ||
| 640 | 654 | return this; | |
| 641 | 655 | } | |
| 642 | 656 | ||
@@ -647,12 +661,16 @@ Socket.prototype.setKeepAlive = function(enable, initialDelayMsecs) { | |||
| 647 | 661 | if (enable !== this[kSetKeepAlive] || | |
| 648 | 662 | ( | |
| 649 | 663 | enable && | |
| 650 | - this[kSetKeepAliveInitialDelay] !== initialDelay | ||
| 664 | + (this[kSetKeepAliveInitialDelay] !== initialDelay || | ||
| 665 | + this[kSetKeepAliveInterval] !== interval || | ||
| 666 | + this[kSetKeepAliveCount] !== count) | ||
| 651 | 667 | ) | |
| 652 | 668 | ) { | |
| 653 | 669 | this[kSetKeepAlive] = enable; | |
| 654 | 670 | this[kSetKeepAliveInitialDelay] = initialDelay; | |
| 655 | - this._handle.setKeepAlive(enable, initialDelay); | ||
| 671 | + this[kSetKeepAliveInterval] = interval; | ||
| 672 | + this[kSetKeepAliveCount] = count; | ||
| 673 | + this._handle.setKeepAlive(enable, initialDelay, interval, count); | ||
| 656 | 674 | } | |
| 657 | 675 | ||
| 658 | 676 | return this; | |
@@ -1676,7 +1694,9 @@ function afterConnect(status, handle, req, readable, writable) { | |||
| 1676 | 1694 | } | |
| 1677 | 1695 | ||
| 1678 | 1696 | if (self[kSetKeepAlive] && self._handle.setKeepAlive) { | |
| 1679 | - self._handle.setKeepAlive(true, self[kSetKeepAliveInitialDelay]); | ||
| 1697 | + self._handle.setKeepAlive(true, self[kSetKeepAliveInitialDelay], | ||
| 1698 | + self[kSetKeepAliveInterval], | ||
| 1699 | + self[kSetKeepAliveCount]); | ||
| 1680 | 1700 | } | |
| 1681 | 1701 | ||
| 1682 | 1702 | if (self[kSetTOS] !== undefined && self._handle.setTypeOfService) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -208,7 +208,14 @@ void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) { | |||
| 208 | 208 | int enable; | |
| 209 | 209 | if (!args[0]->Int32Value(env->context()).To(&enable)) return; | |
| 210 | 210 | unsigned int delay = static_cast<unsigned int>(args[1].As<Uint32>()->Value()); | |
| 211 | - int err = uv_tcp_keepalive(&wrap->handle_, enable, delay); | ||
| 211 | + // interval and count are optional. Fall back to the libuv defaults | ||
| 212 | + // (1 second, 10 probes) when they are not provided so that callers using | ||
| 213 | + // the legacy two-argument form of this handle method keep working. | ||
| 214 | + unsigned int interval = 1; | ||
| 215 | + unsigned int count = 10; | ||
| 216 | + if (args[2]->IsUint32()) interval = args[2].As<Uint32>()->Value(); | ||
| 217 | + if (args[3]->IsUint32()) count = args[3].As<Uint32>()->Value(); | ||
| 218 | + int err = uv_tcp_keepalive_ex(&wrap->handle_, enable, delay, interval, count); | ||
| 212 | 219 | args.GetReturnValue().Set(err); | |
| 213 | 220 | } | |
| 214 | 221 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,106 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const net = require('net'); | ||
| 6 | + | ||
| 7 | + // Verifies that setKeepAlive() forwards the keepalive probe interval | ||
| 8 | + // (TCP_KEEPINTVL) and probe count (TCP_KEEPCNT) to the handle. The interval is | ||
| 9 | + // converted from milliseconds to whole seconds, mirroring the initialDelay | ||
| 10 | + // handling and uv_tcp_keepalive_ex(). | ||
| 11 | + | ||
| 12 | + // Explicit setKeepAlive(enable, initialDelay, interval, count) forwards all | ||
| 13 | + // four values, converting milliseconds to seconds for the delays. | ||
| 14 | + { | ||
| 15 | + const server = net.createServer(); | ||
| 16 | + server.listen(0, common.mustCall(() => { | ||
| 17 | + const client = net.connect( | ||
| 18 | + { port: server.address().port }, | ||
| 19 | + common.mustCall(() => { | ||
| 20 | + client._handle.setKeepAlive = common.mustCall( | ||
| 21 | + (enable, delay, interval, count) => { | ||
| 22 | + assert.strictEqual(enable, true); | ||
| 23 | + assert.strictEqual(delay, 5); | ||
| 24 | + assert.strictEqual(interval, 10); | ||
| 25 | + assert.strictEqual(count, 9); | ||
| 26 | + }); | ||
| 27 | + client.setKeepAlive(true, 5000, 10000, 9); | ||
| 28 | + client.end(); | ||
| 29 | + })); | ||
| 30 | + | ||
| 31 | + client.on('end', common.mustCall(() => server.close())); | ||
| 32 | + })); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + // Omitting interval/count passes undefined through; the handle applies the | ||
| 36 | + // libuv defaults (1s interval, 10 probes). | ||
| 37 | + { | ||
| 38 | + const server = net.createServer(); | ||
| 39 | + server.listen(0, common.mustCall(() => { | ||
| 40 | + const client = net.connect( | ||
| 41 | + { port: server.address().port }, | ||
| 42 | + common.mustCall(() => { | ||
| 43 | + client._handle.setKeepAlive = common.mustCall( | ||
| 44 | + (enable, delay, interval, count) => { | ||
| 45 | + assert.strictEqual(enable, true); | ||
| 46 | + assert.strictEqual(delay, 5); | ||
| 47 | + assert.strictEqual(interval, undefined); | ||
| 48 | + assert.strictEqual(count, undefined); | ||
| 49 | + }); | ||
| 50 | + client.setKeepAlive(true, 5000); | ||
| 51 | + client.end(); | ||
| 52 | + })); | ||
| 53 | + | ||
| 54 | + client.on('end', common.mustCall(() => server.close())); | ||
| 55 | + })); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + // An options object as the first argument is equivalent to the positional | ||
| 59 | + // form, forwarding enable/initialDelay/interval/count to the handle. | ||
| 60 | + { | ||
| 61 | + const server = net.createServer(); | ||
| 62 | + server.listen(0, common.mustCall(() => { | ||
| 63 | + const client = net.connect( | ||
| 64 | + { port: server.address().port }, | ||
| 65 | + common.mustCall(() => { | ||
| 66 | + client._handle.setKeepAlive = common.mustCall( | ||
| 67 | + (enable, delay, interval, count) => { | ||
| 68 | + assert.strictEqual(enable, true); | ||
| 69 | + assert.strictEqual(delay, 5); | ||
| 70 | + assert.strictEqual(interval, 10); | ||
| 71 | + assert.strictEqual(count, 9); | ||
| 72 | + }); | ||
| 73 | + client.setKeepAlive({ | ||
| 74 | + enable: true, | ||
| 75 | + initialDelay: 5000, | ||
| 76 | + interval: 10000, | ||
| 77 | + count: 9, | ||
| 78 | + }); | ||
| 79 | + client.end(); | ||
| 80 | + })); | ||
| 81 | + | ||
| 82 | + client.on('end', common.mustCall(() => server.close())); | ||
| 83 | + })); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + // Omitted options properties behave like omitted positional arguments. | ||
| 87 | + { | ||
| 88 | + const server = net.createServer(); | ||
| 89 | + server.listen(0, common.mustCall(() => { | ||
| 90 | + const client = net.connect( | ||
| 91 | + { port: server.address().port }, | ||
| 92 | + common.mustCall(() => { | ||
| 93 | + client._handle.setKeepAlive = common.mustCall( | ||
| 94 | + (enable, delay, interval, count) => { | ||
| 95 | + assert.strictEqual(enable, true); | ||
| 96 | + assert.strictEqual(delay, 5); | ||
| 97 | + assert.strictEqual(interval, undefined); | ||
| 98 | + assert.strictEqual(count, undefined); | ||
| 99 | + }); | ||
| 100 | + client.setKeepAlive({ enable: true, initialDelay: 5000 }); | ||
| 101 | + client.end(); | ||
| 102 | + })); | ||
| 103 | + | ||
| 104 | + client.on('end', common.mustCall(() => server.close())); | ||
| 105 | + })); | ||
| 106 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments