webrtc / samples

WebRTC Web demos and samples
https://webrtc.github.io/samples
BSD 3-Clause "New" or "Revised" License
13.75k stars 5.69k forks source link

Substitute "Send" for "Transfer": RTCDataChannel send() does not support transferring data #1586

Closed guest271314 closed 1 year ago

guest271314 commented 1 year ago

Browser affected

Chromium 110.

Description

send() of RTCDataChannel does not transfer data within the meaning of Transferable object https://html.spec.whatwg.org/multipage/structured-data.html#transferable-objects.

For disambiguity substitute "Send"/"send" for "Transfer"/"transfer" in

Steps to reproduce

const data = structuredClone(e.data, { transfer: [e.data.buffer] });
channel.send(data);
console.assert(data.byteLength === 0, {data});

Expected results

byteLength of TypedArray to be 0 after being transferred.

Actual results

Assertion failed: 
Object
data:  Uint8Array(8) [116, 114, 97, 110, 115, 102, 101, 114, 
buffer: ArrayBuffer(8), 
byteLength: 8, 
byteOffset: 0, 
length: 8, 
Symbol(Symbol.toStringTag): 'Uint8Array']
fippo commented 1 year ago

https://www.rfc-editor.org/rfc/rfc959 uses "send data" so this seems fine.

For the steps to reproduce I would recommend raising an issue in the W3C org.

guest271314 commented 1 year ago

https://www.rfc-editor.org/rfc/rfc959 uses "send data" so this seems fine.

Not sure what your resolution is re "this seems fine". You don't intend to make the suggested changes?

Some developers actually mean transfer, i.e., Transferable objects https://html.spec.whatwg.org/multipage/structured-data.html#transferable-objects means something specific in on Web platform when they have a specific requirement https://github.com/GoogleChrome/chrome-extensions-samples/issues/766, e.g., cf. IPC messaging.

In this case I was able to create an offscreen document that is closed when the transmission, or "send data" is complete https://github.com/GoogleChrome/chrome-extensions-samples/pull/782. I think the expectation is for the data to actually be transferred, where ArrayBuffer byteLength is 0 after send().

However, in this instance that was the closest I could get, as there is no Web API, or even browser extension API to programmatically set WindowClient of a ServiceWorker or opener of a Window so we can transfer data between cross-origin browsing contexts.

After testing the above code I realized the data is not transferred. I think changing you file names will avoid ambiguity on the Web platform.

For the steps to reproduce I would recommend raising an issue in the W3C org.

W3C banned me.

I think it is important developers know RTCDataChannel does not transfer data as described in Transferable object senction of HTML Standard. I would at least suggest a Note in the specification because MessageEvent is being used to the RTCDataChannel, though like BroadcastChannel, does not actually support Transferable objects - though probably should.

fippo commented 1 year ago

Developers don't expect a file transfer protocol to delete at the source.

This repository is the wrong venue for the argument you are trying to have.

alvestrand commented 1 year ago

The use of "transfer" to mean copying without deletion at source in the title of RFC 959 predates W3C use of the term "transfer" to mean "transfer a copy and destroy the source" by at least 30 years.

The RTCDataChannel "send" operation was modeled on WebSockets. It also predates the "Transferable objects" spec by a considerable number of years.

guest271314 commented 1 year ago

Developers don't expect a file transfer protocol to delete at the source.

In some cases they do. Thanks for your feedback.

The use of "transfer" to mean copying without deletion at source in the title of RFC 959 predates W3C use of the term "transfer" to mean "transfer a copy and destroy the source" by at least 30 years.

The RTCDataChannel "send" operation was modeled on WebSockets. It also predates the "Transferable objects" spec by a considerable number of years.

Thanks for your feedback.

I'm wondering if it is possible to extend (i.e., WebRTC extensions https://github.com/w3c/webrtc-extensions/) send() to have a transferable option; or at least open a discussion about that option?

guest271314 commented 1 year ago

FWIW I figured out how to detach the buffer using https://github.com/tc39/proposal-resizablearraybuffer

    const {byteLength} = e.data;
    console.log(e.data.byteLength); // 895
    channel.send(e.data.transfer(byteLength));
    console.log(e.data.byteLength); // 0