Use persistent WebTransport frame stream
This commit is contained in:
@@ -65,6 +65,7 @@ const JPEG_EOI = Buffer.from([0xff, 0xd9]);
|
||||
const WT_STREAM_CONTROL_TO_CLIENT = 1;
|
||||
const WT_STREAM_FRAME = 2;
|
||||
const WT_STREAM_CONTROL_TO_SERVER = 3;
|
||||
const WT_FRAME_RECORD_HEADER_BYTES = 4;
|
||||
const BEST_EFFORT_RESUME_MAX_SECONDS = 30 * 24 * 60 * 60;
|
||||
const RECORDED_MEDIA_EXTENSIONS = new Set([
|
||||
'.avi',
|
||||
@@ -2524,6 +2525,8 @@ class WebTransportFrameConnection extends EventEmitter {
|
||||
this._closedEmitted = false;
|
||||
this._controlStreamPromise = this.openControlStream();
|
||||
this._controlWrite = Promise.resolve();
|
||||
this._frameStreamPromise = null;
|
||||
this._frameWrite = Promise.resolve();
|
||||
|
||||
this.session.closed().then((info) => {
|
||||
this.markClosed(info?.closeCode ?? 1000, info?.reason ?? '');
|
||||
@@ -2554,7 +2557,11 @@ class WebTransportFrameConnection extends EventEmitter {
|
||||
}
|
||||
|
||||
const packet = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
||||
this.writeFrame(packet).then(() => {
|
||||
this._frameWrite = this._frameWrite
|
||||
.catch(() => {})
|
||||
.then(() => this.writeFrame(packet));
|
||||
|
||||
this._frameWrite.then(() => {
|
||||
done?.();
|
||||
}).catch((error) => {
|
||||
this.emitError(error);
|
||||
@@ -2583,6 +2590,17 @@ class WebTransportFrameConnection extends EventEmitter {
|
||||
return stream;
|
||||
}
|
||||
|
||||
async openFrameStream() {
|
||||
const stream = await this.session.openUni();
|
||||
await stream.write(Buffer.from([WT_STREAM_FRAME]));
|
||||
return stream;
|
||||
}
|
||||
|
||||
getFrameStream() {
|
||||
this._frameStreamPromise ??= this.openFrameStream();
|
||||
return this._frameStreamPromise;
|
||||
}
|
||||
|
||||
async writeControl(data) {
|
||||
if (this.readyState !== WebSocket.OPEN) {
|
||||
return;
|
||||
@@ -2597,17 +2615,20 @@ class WebTransportFrameConnection extends EventEmitter {
|
||||
throw new Error('WebTransport frame connection is closed.');
|
||||
}
|
||||
|
||||
this._bufferedAmount += packet.length;
|
||||
if (packet.length > 0xffffffff) {
|
||||
throw new Error('WebTransport frame packet is too large.');
|
||||
}
|
||||
|
||||
const recordHeader = Buffer.allocUnsafe(WT_FRAME_RECORD_HEADER_BYTES);
|
||||
recordHeader.writeUInt32LE(packet.length, 0);
|
||||
this._bufferedAmount += WT_FRAME_RECORD_HEADER_BYTES + packet.length;
|
||||
|
||||
try {
|
||||
const stream = await this.session.openUni();
|
||||
const payload = Buffer.allocUnsafe(packet.length + 1);
|
||||
payload[0] = WT_STREAM_FRAME;
|
||||
packet.copy(payload, 1);
|
||||
await stream.write(payload);
|
||||
await stream.finish();
|
||||
const stream = await this.getFrameStream();
|
||||
await stream.write(recordHeader);
|
||||
await stream.write(packet);
|
||||
} finally {
|
||||
this._bufferedAmount = Math.max(0, this._bufferedAmount - packet.length);
|
||||
this._bufferedAmount = Math.max(0, this._bufferedAmount - WT_FRAME_RECORD_HEADER_BYTES - packet.length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user