WebUSB API, Web tarayıcınızda USB aygıtından veri okumayı ve yazmayı mümkün hale getirebilmek için tasarlanan bir arabirimdir.
Açık ve basit bir şekilde "USB" deseydim, aklınıza hemen klavyeler, fareler, ses, video ve depolama aygıtları gelme ihtimali yüksek. Haklısın ama orada başka türde Evrensel Seri Veri Yolu (USB) aygıtları da bulacaksın.
Bu standartlaştırılmamış USB aygıtları, sizin (geliştiricinin) bunlardan yararlanabilmeniz için donanım satıcılarının platforma özel sürücüler ve SDK'lar yazmasını gerektirir. Ne yazık ki bu platforma özgü kod, bu cihazların Web tarafından kullanılmasını tarihsel olarak engelledi. WebUSB API'sinin yaratılmasının nedenlerinden biri de budur: USB cihaz hizmetlerini Web'e sunmanın bir yolunu sağlamak. Bu API ile donanım üreticileri, cihazları için platformlar arası JavaScript SDK'ları oluşturabilecekler. Ama en önemlisi bu, USB'yi Web'e getirerek daha güvenli ve kullanımı daha kolay hale getirecektir .
WebUSB API ile bekleyebileceğiniz davranışa bakalım:
- Bir USB cihazı satın alın.
- Bilgisayarınıza takın. Bu cihaz için gidilecek doğru web sitesiyle birlikte hemen bir bildirim görünür.
- Bildirimi tıklayın. Web sitesi orada ve kullanıma hazır!
- Bağlanmak için tıklayın ve Chrome'da cihazınızı seçebileceğiniz bir USB cihaz seçici belirir.
WebUSB API'si olmadan bu prosedür nasıl olurdu?
- Platforma özel bir uygulama yükleyin.
- İşletim sistemimde bile destekleniyorsa, doğru şeyi indirdiğimi doğrulayın.
- Şeyi kurun. Şanslıysanız, sizi internetten sürücü/uygulama yükleme konusunda uyaran korkutucu işletim sistemi istemleri veya açılır pencereleri almazsınız. Şanssızsanız, yüklü sürücüler veya uygulamalar arızalanır ve bilgisayarınıza zarar verir. (Unutmayın, web, arızalı web sitelerini içerecek şekilde oluşturulmuştur ).
- Özelliği yalnızca bir kez kullanırsanız, kod siz onu kaldırmayı düşünene kadar bilgisayarınızda kalır. (Web'de kullanılmayan alan sonunda geri alınır.)
Başlamadan önce #
Bu makale, USB'nin nasıl çalıştığına dair bazı temel bilgilere sahip olduğunuzu varsaymaktadır. Değilse, USB'yi NutShell'de okumanızı öneririm . USB hakkında arka plan bilgisi için resmi USB özelliklerine bakın .
WebUSB API Chrome 61 mevcuttur.
Menşe denemeleri için kullanılabilir #
Sahada WebUSB API'sini kullanan geliştiricilerden mümkün olduğunca fazla geri bildirim almak için, bu özelliği daha önce Chrome 54 ve Chrome 57'de bir Origin deneme sürümü olarak eklemiştik .
En son deneme, Eylül 2017'de başarıyla sona erdi.
Gizlilik ve güvenlik #
Yalnızca HTTPS #
Bu özelliğin gücü nedeniyle yalnızca güvenli bağlamlarda çalışır . Bu, TLS'yi göz önünde bulundurarak oluşturmanız gerekeceği anlamına gelir .
Kullanıcı hareketi gerekli #
Güvenlik önlemi olarak, navigator.usb.requestDevice()yalnızca dokunma veya fare tıklaması gibi bir kullanıcı hareketiyle çağrılabilir.
Özellik Politikası #
Bir özellik politika geliştiriciler seçici etkinleştirme ve devre dışı bırakma çeşitli tarayıcı özellikleri ve API'leri sağlayan bir mekanizmadır. Bir HTTP başlığı ve/veya bir iframe "izin ver" niteliği aracılığıyla tanımlanabilir.
Usb özniteliğinin Navigator nesnesinde gösterilip gösterilmeyeceğini veya başka bir deyişle WebUSB'ye izin verip vermediğini kontrol eden bir özellik politikası tanımlayabilirsiniz.
Aşağıda, WebUSB'ye izin verilmeyen bir başlık politikası örneği verilmiştir:
Feature-Policy: fullscreen "*"; usb "none"; payment "self" https://payment.example.com
# kodlamaya başlayalım
WebUSB API JavaScript dayanır Promises . Bunlara aşina değilseniz, bu harika Vaatler eğitimine göz atın . Bir şey daha () => {}, basitçe ECMAScript 2015 Ok işlevleridir .
USB cihazlarına erişim sağlayın #
Kullanıcıyı kullanarak tek bir bağlı USB cihazı seçmesini isteyebilir navigator.usb.requestDevice()veya navigator.usb.getDevices()kaynağın erişimi olan tüm bağlı USB cihazlarının bir listesini almak için arayabilirsiniz .
navigator.usb.requestDevice()Fonksiyon tanımlaması zorunlu bir JavaScript nesnesi alır filters. Bu filtreler, herhangi bir USB cihazını verilen satıcı ( vendorId) ve isteğe bağlı olarak ürün ( productId) tanımlayıcılarıyla eşleştirmek için kullanılır . classCode, protocolCode, serialNumberVe subclassCodetuşları da orada tanımlanabilir.

USB cihazı kullanıcı istemi.
Örneğin, orijine izin verecek şekilde yapılandırılmış bağlı bir Arduino cihazına nasıl erişileceği aşağıda açıklanmıştır.
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(device => {
console.log(device.productName); // "Arduino Micro"
console.log(device.manufacturerName); // "Arduino LLC"
})
.catch(error => { console.error(error); });
Siz sormadan önce, sihirli bir şekilde bu 0x2341onaltılık sayıyı bulmadım. Bu USB Kimlik Listesi'nde "Arduino" kelimesini aradım .
deviceYukarıdaki taahhütte iade edilen USB , desteklenen USB sürümü, maksimum paket boyutu, satıcı ve ürün kimlikleri, cihazın sahip olabileceği olası yapılandırma sayısı gibi cihazla ilgili bazı temel ancak önemli bilgilere sahiptir. Temel olarak cihaz USB Tanımlayıcısındaki tüm alanları içerir .
Bu arada, bir USB cihazı WebUSB desteğini duyurursa ve bir açılış sayfası URL'si tanımlarsa, Chrome, USB cihazı takıldığında kalıcı bir bildirim gösterir. Bu bildirime tıklandığında açılış sayfası açılır.

WebUSB bildirimi.
Buradan navigator.usb.getDevices()Arduino cihazınızı aşağıda gösterildiği gibi arayabilir ve erişebilirsiniz.
navigator.usb.getDevices().then(devices => {
devices.forEach(device => {
console.log(device.productName); // "Arduino Micro"
console.log(device.manufacturerName); // "Arduino LLC"
});
})
Bir Arduino USB kartıyla konuşun #
Tamam, şimdi bir WebUSB uyumlu Arduino kartından USB portu üzerinden iletişim kurmanın ne kadar kolay olduğunu görelim. Adresindeki talimatları göz atın https://github.com/webusb/arduino için WebUSB etkinleştirmek çizimler .
Merak etmeyin, bu makalenin ilerleyen kısımlarında aşağıda bahsedilen tüm WebUSB cihaz yöntemlerini ele alacağım.
let device;
navigator.usb.requestDevice({ filters: [{ vendorId: 0x2341 }] })
.then(selectedDevice => {
device = selectedDevice;
return device.open(); // Begin a session.
})
.then(() => device.selectConfiguration(1)) // Select configuration #1 for the device.
.then(() => device.claimInterface(2)) // Request exclusive control over interface #2.
.then(() => device.controlTransferOut({
requestType: 'class',
recipient: 'interface',
request: 0x22,
value: 0x01,
index: 0x02})) // Ready to receive data
.then(() => device.transferIn(5, 64)) // Waiting for 64 bytes of data from endpoint #5.
.then(result => {
const decoder = new TextDecoder();
console.log('Received: ' + decoder.decode(result.data));
})
.catch(error => { console.error(error); });
Lütfen burada kullandığım WebUSB kitaplığının yalnızca bir örnek protokolü (standart USB seri protokolüne dayalı olarak) uyguladığını ve üreticilerin istedikleri herhangi bir dizi ve türde uç nokta oluşturabileceklerini unutmayın. Kontrol transferleri özellikle küçük konfigürasyon komutları için güzeldir, çünkü bus önceliği vardır ve iyi tanımlanmış bir yapıya sahiptirler.
Ve işte Arduino panosuna yüklenen taslak.
// Third-party WebUSB Arduino library
#include
WebUSB WebUSBSerial(1 /* https:// */, "webusb.github.io/arduino/demos");
#define Serial WebUSBSerial
void setup() {
Serial.begin(9600);
while (!Serial) {
; // Wait for serial port to connect.
}
Serial.write("WebUSB FTW!");
Serial.flush();
}
void loop() {
// Nothing here for now.
}
Yukarıdaki örnek kodda kullanılan üçüncü taraf WebUSB Arduino kütüphanesi temelde iki şey yapar:
- Cihaz, Chrome'un açılış sayfası URL'sini okumasını sağlayan bir WebUSB cihazı gibi davranır .
- Varsayılanı geçersiz kılmak için kullanabileceğiniz bir WebUSB Seri API'sini sunar.
JavaScript koduna tekrar bakın. deviceKullanıcı tarafından seçildikten sonra device.open(), USB cihazıyla bir oturum başlatmak için platforma özel tüm adımları çalıştırır. Ardından, kullanılabilir bir USB Yapılandırması seçmem gerekiyor device.selectConfiguration(). Bir konfigürasyonun cihaza nasıl güç verildiğini, maksimum güç tüketimini ve arayüz sayısını belirlediğini unutmayın. Arayüzlerden bahsetmişken, ayrıca özel erişim talep etmem gerekiyor device.claimInterface()çünkü veriler sadece arayüz talep edildiğinde bir arayüze veya ilişkili uç noktalara aktarılabilir. Son olarak device.controlTransferOut(), Arduino cihazını WebUSB Seri API üzerinden iletişim kurmak için uygun komutlarla kurmak için arama gereklidir.
Oradan device.transferIn(), ana bilgisayarın toplu veri almaya hazır olduğunu bildirmek için cihaza toplu aktarım gerçekleştirir. Ardından, uygun şekilde ayrıştırılması gereken resultbir DataView içeren bir nesne ile söz yerine getirilir data.
USB'ye aşina iseniz, bunların hepsi oldukça tanıdık gelmelidir.
daha fazlasını istiyorum #
WebUSB API, tüm USB aktarım/uç nokta türleri ile etkileşime girmenizi sağlar:
- Yapılandırma veya komut parametrelerini bir USB cihazına göndermek veya almak için kullanılan KONTROL aktarımları
controlTransferIn(setup, length)ve ile işlenircontrolTransferOut(setup, data). - Az miktarda zamana duyarlı veri için kullanılan INTERRUPT transferleri,
transferIn(endpointNumber, length)ve ile BULK transferleriyle aynı yöntemlerle işlenirtransferOut(endpointNumber, data). - Video ve ses gibi veri akışları için kullanılan İzokronİk transferler, ile işlenir
isochronousTransferIn(endpointNumber, packetLengths)veisochronousTransferOut(endpointNumber, data, packetLengths). - Büyük miktarda zamana duyarlı olmayan veriyi güvenilir bir şekilde aktarmak için kullanılan BULK aktarımları
transferIn(endpointNumber, length)ve ile işlenirtransferOut(endpointNumber, data).
Ayrıca Mike Tsao'nun WebUSB API için tasarlanmış USB kontrollü bir LED cihazı oluşturmanın temel bir örneğini sağlayan WebLight projesine de bir göz atmak isteyebilirsiniz (burada bir Arduino kullanmadan). Donanım, yazılım ve bellenim bulacaksınız.
İpuçları #
about://device-logUSB cihazıyla ilgili tüm olayları tek bir yerde görebileceğiniz dahili sayfa sayesinde Chrome'da USB hatalarını ayıklamak daha kolaydır .

WebUSB API'sinde hata ayıklamak için Chrome'daki cihaz günlüğü sayfası.
Dahili sayfa about://usb-internalsda kullanışlıdır ve sanal WebUSB cihazlarının bağlantısını ve bağlantısını kesmenizi simüle etmenize olanak tanır. Bu, gerçek donanım olmadan UI testi yapmak için kullanışlıdır.

WebUSB API'sinde hata ayıklamak için Chrome'daki dahili sayfa.
Çoğu Linux sisteminde, USB aygıtları varsayılan olarak salt okunur izinlerle eşlenir. Chrome'un bir USB cihazı açmasına izin vermek için yeni bir udev kuralı eklemeniz gerekir . /etc/udev/rules.d/50-yourdevicename.rulesAşağıdaki içeriğe sahip bir dosya oluşturun :
SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
nerede [yourdevicevendor]olduğunu 2341cihazınız örneğin bir Arduino ise. ATTR{idProduct}daha spesifik bir kural için de eklenebilir. Emin senin olun userbir olan üye arasında plugdevgrubundan. Ardından, cihazınızı yeniden bağlamanız yeterlidir.
Arduino örnekleri tarafından kullanılan Microsoft OS 2.0 Tanımlayıcıları yalnızca Windows 8.1 ve sonraki sürümlerde çalışır. Bu Windows desteği olmadan hala bir INF dosyasının manuel olarak yüklenmesi gerekir.
Kaynaklar #
- Yığın Taşması: https://stackoverflow.com/questions/tagged/webusb
- WebUSB API Özelliği: http://wicg.github.io/webusb/
- Chrome Özellik Durumu: https://www.chromestatus.com/feature/5651917954875392
- Özellik Sorunları: https://github.com/WICG/webusb/issues
- Uygulama Hataları: http://crbug.com?q=component:Blink>USB
- WebUSB ❤ ️Arduino: https://github.com/webusb/arduino
- IRC: W3C'nin IRC'sinde #webusb
- WICG Posta listesi: https://lists.w3.org/Archives/Public/public-wicg/
- WebLight projesi: https://github.com/sowbug/weblight