Include an example for WebUSB use in Dedicated Workers
I don't think anything needs to change in the algorithms to support Web Workers but we should add a worker example to the spec. I don't think we have to do that in this patch. Wait until we've added a worker to an existing WebUSB app and have a sense of the best practices.
Originally posted by @reillyeon in https://github.com/WICG/webusb/pull/130
Do WebUSB workers work (in Chrome)? I tried it (in 2022), and it didn't.
@7ombie, we have test cases for Dedicated Worker support in Web Platform Tests so it should work. Note that you cannot call navigator.usb.requestDevice() from a worker. You must call it from a window and then call navigator.usb.getDevices() in the worker to get the device that was selected by the user.
Thank you, @reillyeon. That's almost certainly where I went wrong.
I'm working with realtime audio, so really wanted a dedicated thread for the incoming USB that shares memory (a ring-buffer) with an audio worklet. Handling isochronous USB on the main thread was never going to work as well.
I have implemented a system (currently undergoing internal Engineering Review and not publicly available, sorry) which uses a Worker for device communications. As mentioned above, the requestDevice() function isn't available in the Worker as part of the security of the spec is that it requires direct human interaction to authorise connecting to a device.
The issue is you can't pass the device object over a message to the Worker so currently I am passing the index of the selected device from the getDevices() function to the Worker and then connecting. This works, but I would feel better if there was a more robust way to exactly identify the selected device on both sides.
Agreed that it is currently hard to communicate between a document and worker about what device the user has selected. One option is to make the USBDevice interface transferrable. This would be the "easiest" API but there are some semantic questions that need to be answered such as what state the device must be in to be transferable. It's probably best to require the device to be closed so that there aren't any questions of what happens to in-progress state changes or transfers. There are also some internal architectural challenges in Chromium to implementing transferability for this interface which would need to be ironed out.
The other option is to implement an id attribute like there is on the BluetoothDevice interface which uniquely identifies a device across all same-origin contexts. The existing vendorId, productId and serialNumber fields can be used to approximate this but aren't guaranteed to be unique. I'm leaning towards this option as the faster path to improving this.