* Send a datagram. The id of the sent datagram will be returned. The status * of the sent datagram will be reported via the datagram-status event if * possible. * * If a string is given it will be encoded using the specified encoding. * * If an ArrayBufferView is given, the bytes a
(datagram, encoding = 'utf8')
| 3354 | * @returns {Promise<bigint>} The datagram ID |
| 3355 | */ |
| 3356 | async sendDatagram(datagram, encoding = 'utf8') { |
| 3357 | assertIsQuicSession(this); |
| 3358 | if (this.#isClosedOrClosing) { |
| 3359 | throw new ERR_INVALID_STATE('Session is closed'); |
| 3360 | } |
| 3361 | |
| 3362 | const maxDatagramSize = this.#inner.state.maxDatagramSize; |
| 3363 | |
| 3364 | // The peer max datagram size is either unknown or they have explicitly |
| 3365 | // indicated that they do not support datagrams by setting it to 0. In |
| 3366 | // either case, we do not send the datagram. |
| 3367 | if (maxDatagramSize === 0) return kNilDatagramId; |
| 3368 | |
| 3369 | if (isPromise(datagram)) { |
| 3370 | datagram = await datagram; |
| 3371 | // Session may have closed while awaiting. Since datagrams are |
| 3372 | // inherently unreliable, silently return rather than throwing. |
| 3373 | if (this.#isClosedOrClosing) return kNilDatagramId; |
| 3374 | } |
| 3375 | |
| 3376 | if (typeof datagram === 'string') { |
| 3377 | datagram = new Uint8Array(Buffer.from(datagram, encoding)); |
| 3378 | } else if (!isArrayBufferView(datagram)) { |
| 3379 | throw new ERR_INVALID_ARG_TYPE('datagram', |
| 3380 | ['ArrayBufferView', 'string'], |
| 3381 | datagram); |
| 3382 | } |
| 3383 | |
| 3384 | const length = isDataView(datagram) ? |
| 3385 | DataViewPrototypeGetByteLength(datagram) : |
| 3386 | TypedArrayPrototypeGetByteLength(datagram); |
| 3387 | |
| 3388 | // If the view has zero length (e.g. detached buffer), there's |
| 3389 | // nothing to send. |
| 3390 | if (length === 0) return kNilDatagramId; |
| 3391 | |
| 3392 | // The peer max datagram size is less than the datagram we want to send, |
| 3393 | // so... don't send it. |
| 3394 | if (length > maxDatagramSize) return kNilDatagramId; |
| 3395 | |
| 3396 | const id = this.#handle.sendDatagram(datagram); |
| 3397 | |
| 3398 | if (id !== kNilDatagramId && onSessionSendDatagramChannel.hasSubscribers) { |
| 3399 | onSessionSendDatagramChannel.publish({ |
| 3400 | __proto__: null, |
| 3401 | id, |
| 3402 | length, |
| 3403 | session: this, |
| 3404 | }); |
| 3405 | } |
| 3406 | |
| 3407 | debug(`datagram ${id} sent with ${length} bytes`); |
| 3408 | return id; |
| 3409 | } |
| 3410 | |
| 3411 | /** |
| 3412 | * Initiate a key update. |
no test coverage detected