WICG / webusb

Connecting hardware to the web.
https://wicg.github.io/webusb/
Other
1.3k stars 126 forks source link

Feature request: transferIn listener #229

Closed nico-martin closed 1 year ago

nico-martin commented 1 year ago

If I have understood correctly, I currently have to build a loop to receive data via transferIn.

const readLoop = async () => {
  // listening to 64 bytes on endpoint 3
  const result = await device.transferIn(3, 64);
  result.data && console.log(result.data);
  readLoop();
};
readLoop();

Wouldn't it be more convenient if the WebUSB API provided a listener that passed incoming data to a callback? Similar to the characteristicvaluechanged event in the WebBluetooth API?

// callback when endpoint 3 receives data
device.addEventListener( 'transferIn', 3, (event) => {
  console.log(event.target.value);
});

Or are there specific reasons against such an idea?

reillyeon commented 1 year ago

This doesn't work because all USB transactions are host-initiated. Even for data "sent by" the device the host has to ask for it first and the device has the option to respond or not.

I have considered an API like this but it would require an initial configuration step where the application tells the browser the endpoints and transfer sizes it wants to constantly maintain requests on and then the browser creates the actual transfers and fires an event when they complete. You also want to have back-pressure (so the application doesn't get flooded with input) and so using a ReadableStream would be a better interface.

In the end this is all something you could polyfill in JavaScript and so I decided to keep the API closer to how the USB protocol and OS-level interface actually work.

nico-martin commented 1 year ago

Thank you very much for your comments. It makes sense that the API should be close to the OS interface. And as you say, it's easy to polyfill in the app itself.