@@ -452,6 +452,48 @@ changes: |
452 | 452 | Calls [`server.close()`][] and returns a promise that fulfills when the |
453 | 453 | server has closed. |
454 | 454 |
|
| 455 | +### `server[Symbol.asyncIterator]()` |
| 456 | + |
| 457 | +<!-- YAML |
| 458 | +added: REPLACEME |
| 459 | +--> |
| 460 | + |
| 461 | +> Stability: 1 - Experimental |
| 462 | +
|
| 463 | +* Returns: {AsyncIterator} An async iterator that yields each incoming |
| 464 | + [`net.Socket`][]. |
| 465 | + |
| 466 | +Returns an async iterator over the server's incoming connections, allowing them |
| 467 | +to be consumed with `for await...of` as an alternative to the [`'connection'`][] |
| 468 | +event. Iteration ends when the server emits [`'close'`][], and rejects if the |
| 469 | +server emits [`'error'`][]. |
| 470 | + |
| 471 | +The loop only advances to the next connection once the current iteration's body |
| 472 | +has finished awaiting, so connection handling should be dispatched to a separate |
| 473 | +async task rather than awaited inline. Otherwise connections are serialized: |
| 474 | +each one waits for the previous to be fully handled. |
| 475 | + |
| 476 | +```mjs |
| 477 | +import { createServer } from 'node:net'; |
| 478 | + |
| 479 | +const server = createServer().listen(8124); |
| 480 | + |
| 481 | +async function handleConnection(socket) { |
| 482 | + // ...handle the connection, awaiting as needed. |
| 483 | + socket.end('hello world!'); |
| 484 | +} |
| 485 | + |
| 486 | +for await (const socket of server) { |
| 487 | + // Dispatch handling to a separate task so the loop keeps accepting |
| 488 | + // connections instead of serializing them. |
| 489 | + handleConnection(socket); |
| 490 | +} |
| 491 | +``` |
| 492 | + |
| 493 | +The server does not stop accepting connections while the loop body runs, so a |
| 494 | +consumer slower than the connection rate can buffer them without bound. Use |
| 495 | +[`server.maxConnections`][] to bound concurrency. |
| 496 | + |
455 | 497 | ### `server.getConnections(callback)` |
456 | 498 |
|
457 | 499 | <!-- YAML |
@@ -2276,6 +2318,82 @@ net.isIPv6('::1'); // returns true |
2276 | 2318 | net.isIPv6('fhqwhgads'); // returns false |
2277 | 2319 | ``` |
2278 | 2320 |
|
| 2321 | +## `net/promises` API |
| 2322 | + |
| 2323 | +<!-- YAML |
| 2324 | +added: REPLACEME |
| 2325 | +--> |
| 2326 | + |
| 2327 | +> Stability: 1 - Experimental |
| 2328 | +
|
| 2329 | +The `net/promises` API provides a set of `net` functions that return `Promise` |
| 2330 | +objects rather than relying on events. The API is accessible via |
| 2331 | +`require('node:net').promises` or `require('node:net/promises')`. |
| 2332 | + |
| 2333 | +### `netPromises.connect(options)` |
| 2334 | + |
| 2335 | +### `netPromises.connect(path)` |
| 2336 | + |
| 2337 | +### `netPromises.connect(port[, host])` |
| 2338 | + |
| 2339 | +<!-- YAML |
| 2340 | +added: REPLACEME |
| 2341 | +--> |
| 2342 | + |
| 2343 | +* `options` {Object} Accepts the same arguments as [`net.connect()`][]. May |
| 2344 | + include a `signal` {AbortSignal} that can be used to abort an in-progress |
| 2345 | + connection attempt. |
| 2346 | +* Returns: {Promise} Fulfills with a connected [`net.Socket`][]. |
| 2347 | + |
| 2348 | +A promise-based alternative to [`net.connect()`][]. The returned promise is |
| 2349 | +fulfilled with the socket once its [`'connect'`][] event fires, and is rejected |
| 2350 | +if the connection fails or the `signal` is aborted. When the promise rejects, |
| 2351 | +the underlying socket is destroyed. |
| 2352 | + |
| 2353 | +This API is named for the action it performs and awaits — connecting — to |
| 2354 | +parallel [`netPromises.listen()`][]. It is not named `createConnection()`, |
| 2355 | +because that name belongs to the socket-factory taxonomy of the callback API, |
| 2356 | +which has no counterpart here. |
| 2357 | + |
| 2358 | +```mjs |
| 2359 | +import { connect } from 'node:net/promises'; |
| 2360 | + |
| 2361 | +const socket = await connect({ port: 8124 }); |
| 2362 | +socket.write('hello world!'); |
| 2363 | +socket.end(); |
| 2364 | +``` |
| 2365 | + |
| 2366 | +### `netPromises.listen([options])` |
| 2367 | + |
| 2368 | +<!-- YAML |
| 2369 | +added: REPLACEME |
| 2370 | +--> |
| 2371 | + |
| 2372 | +* `options` {Object} Accepts the same options as [`net.createServer()`][] and |
| 2373 | + [`server.listen()`][], plus: |
| 2374 | + * `connectionListener` {Function} Automatically set as a listener for the |
| 2375 | + [`'connection'`][] event. |
| 2376 | + * `signal` {AbortSignal} An `AbortSignal` that may be used to abort the |
| 2377 | + server. Aborting before the server is listening rejects the returned |
| 2378 | + promise with an `AbortError`; aborting at any later point closes the |
| 2379 | + server, matching the `signal` option of [`server.listen()`][]. |
| 2380 | +* Returns: {Promise} Fulfills with a listening [`net.Server`][]. |
| 2381 | + |
| 2382 | +Creates a [`net.Server`][] and begins listening. The returned promise is |
| 2383 | +fulfilled with the server once its [`'listening'`][] event fires, and is |
| 2384 | +rejected if the server fails to bind or the `signal` is aborted before it is |
| 2385 | +listening. When the promise rejects, the server is closed. |
| 2386 | + |
| 2387 | +The resolved server is async iterable, so incoming connections can be consumed |
| 2388 | +with `for await...of` (see `server[Symbol.asyncIterator]()`). |
| 2389 | + |
| 2390 | +```mjs |
| 2391 | +import { listen } from 'node:net/promises'; |
| 2392 | + |
| 2393 | +const server = await listen({ port: 8124 }); |
| 2394 | +console.log('listening on', server.address().port); |
| 2395 | +``` |
| 2396 | + |
2279 | 2397 | [IPC]: #ipc-support |
2280 | 2398 | [Identifying paths for IPC connections]: #identifying-paths-for-ipc-connections |
2281 | 2399 | [RFC 8305]: https://www.rfc-editor.org/rfc/rfc8305.txt |
@@ -2310,6 +2428,7 @@ net.isIPv6('fhqwhgads'); // returns false |
2310 | 2428 | [`net.createServer()`]: #netcreateserveroptions-connectionlistener |
2311 | 2429 | [`net.getDefaultAutoSelectFamily()`]: #netgetdefaultautoselectfamily |
2312 | 2430 | [`net.getDefaultAutoSelectFamilyAttemptTimeout()`]: #netgetdefaultautoselectfamilyattempttimeout |
| 2431 | +[`netPromises.listen()`]: #netpromiseslistenoptions |
2313 | 2432 | [`new net.Socket(options)`]: #new-netsocketoptions |
2314 | 2433 | [`readable.setEncoding()`]: stream.md#readablesetencodingencoding |
2315 | 2434 | [`server.address()`]: #serveraddress |
|