WebUSB API, USB'yi web'e taşıyarak daha güvenli ve kolay bir şekilde kullanılmasını sağlar.
Sade bir şekilde ve sadece "USB" dediysem klavyeleri, fareleri, sesleri, videoları ve depolama cihazlarını hemen düşünün. Artık ama başka türlerde Universal Serial Bus (USB) cihazları da vardır. inceleyeceğiz.
Bu standart olmayan USB cihazları, donanım tedarikçilerinin platforma özgü metin yazması gerekir sizin (geliştirici) yararlanabilmeniz için sürücüleri ve SDK'ları Ne yazık ki bu platforma özgü kod, geçmişte bu cihazların kullanılmasını engelliyordu sunar. WebUSB API'nin oluşturulma nedenlerinden biri de budur: USB cihaz hizmetlerinin Web'de açığa çıkarılması için bir yöntem sağlar. Bu API ile donanım, üreticiler, kendileri için platformlar arası JavaScript SDK'ları oluşturabilecek, cihazlar.
Ancak en önemlisi de bu; ya da yeni bir özellik oluşturarak USB'nin web'e iletebilir.
WebUSB API'de karşılaşabileceğiniz davranışı inceleyelim:
- Bir USB cihazı satın alın.
- Bilgisayarınıza takın. Hemen bir bildirim görünür ve bu cihaz için gidilecek bir web sitesi.
- Bildirimi tıklayın. Web sitesi hazır ve kullanıma hazır.
- Bağlanmak için tıklayın. Chrome'da bir USB cihaz seçici görünür. Buradan, cihazınızı seçin.
İşte oldu!
WebUSB API olmadan bu prosedür nasıl olurdu?
- Platforma özel bir uygulama yükleyin.
- İşletim sistemimde destekleniyorsa dosyayı indirdiğimden emin olmak için emin olmanız gerekir.
- Ürünü yükleyin. Şanslıysanız korkutucu işletim sistemi istemleri veya pop-up'larla karşılaşmazsınız İnternet'ten sürücü/uygulama yükleme konusunda sizi uyarır. Eğer şanssızsanız yüklü sürücüler veya uygulamalar hatalı çalışır ve zarar görür bilgisayarınızdan erişebilirsiniz. (Web'in, kalite standartlarının hatalı olabilecek ziyaret edin).
- Bu özelliği yalnızca bir kez kullanırsanız kod siz izin verene kadar bilgisayarınızda kalır. kaldırabilirsiniz. (Web'de kullanılmayan alan nihayetinde reclaimed.)
Başlamadan önce
Bu makalede USB'nin işleyişiyle ilgili bazı temel bilgilere sahip olduğunuz varsayılmaktadır. Aksi halde NutShell'de USB'yi okumanızı öneririz. USB hakkında arka plan bilgileri için resmi USB özelliklerine göz atın.
WebUSB API, Chrome 61'de kullanılabilir.
Kaynak denemeleri için kullanılabilir
WebUSB kullanan geliştiricilerden mümkün olduğunca fazla geri bildirim almak için Chrome 54 ve Chrome'a bu özelliği daha önce ekledik, 57'yi kaynak denemesinde kullanabilirsiniz.
Son deneme sürümü Eylül 2017'de başarıyla sona erdi.
Gizlilik ve güvenlik
Yalnızca HTTPS
Bu özellik, gücü sayesinde yalnızca güvenli bağlamlarda çalışır. Bunun anlamı şudur: TLS'yi göz önünde bulundurarak geliştirmeniz gerekir.
Kullanıcı hareketi gerekli
Güvenlik önlemi olarak navigator.usb.requestDevice()
,
Dokunma veya fare tıklaması gibi bir kullanıcı hareketiyle çağrılabilir.
İzin Politikası
İzin Politikası, geliştiricilerin istediklerini seçmelerine olanak tanıyan bir mekanizmadır ve çeşitli tarayıcı özelliklerini ve API'leri devre dışı bırakın. HTTP üzerinden tanımlanabilir üstbilgi ve/veya iframe "allow" özelliğini gönderin.
usb
özelliğinin
Navigator nesnesinde gösterilir veya diğer bir deyişle WebUSB'ye izin verirseniz
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
Aşağıda, USB'ye izin verilen bir kapsayıcı politikasına başka bir örnek verilmiştir:
<iframe allowpaymentrequest allow="usb; fullscreen"></iframe>
Kodlamaya başlayalım
WebUSB API, yoğun olarak JavaScript Promises'i kullanır. Bilmiyorsanız
daha fazla bilgi için bu Promises eğiticisini inceleyin. Bir şey daha, () => {}
basitçe ECMAScript 2015 ok işlevleridir.
USB cihazlarına erişim elde etme
Kullanıcıdan bağlı tek bir USB cihazını seçmesini isteyebilirsiniz:
navigator.usb.requestDevice()
veya navigator.usb.getDevices()
numaralı telefonu arayarak
web sitesinin erişmesine izin verilen tüm bağlı USB cihazlarının listesi.
navigator.usb.requestDevice()
işlevi, zorunlu bir JavaScript nesnesi alıyor
filters
öğesini tanımlayan bir ifadedir. Bu filtreler, USB cihazlarıyla bu cihazları eşleştirmek için kullanılır
sağlanan tedarikçi firma (vendorId
) ve isteğe bağlı olarak ürün (productId
) tanımlayıcıları.
classCode
, protocolCode
, serialNumber
ve subclassCode
anahtarları
burada da tanımlanmalıdır.
Örneğin, yapılandırılmış başka bir Arduino cihazına tıklayın.
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, bu 0x2341
onaltılık sayıyı sihirli bir şekilde düşünmemiştim
sayı. "Arduino" kelimesini aradım USB Kimlikleri listesindeki bilgileri inceleyin.
Yukarıda belirtilen sözü yerine getiren USB device
cihazındaki bazı temel özellikler
cihazla ilgili önemli bilgileri (ör. desteklenen USB sürümü,
paket boyutunu, tedarikçiyi ve ürün kimliklerini, olası
yapılandırmanın ne kadar önemli olduğu. Temelde bu dosya,
cihaz USB Tanımlayıcısı.
// Get all connected USB devices the website has been granted access to.
navigator.usb.getDevices().then(devices => {
devices.forEach(device => {
console.log(device.productName); // "Arduino Micro"
console.log(device.manufacturerName); // "Arduino LLC"
});
})
Bu arada, bir USB cihazı WebUSB desteğini bir açılış sayfası URL'si tanımlarsanız USB cihazı takılı. Bu bildirimi tıkladığınızda açılış sayfası açılır.
Arduino USB kartı ile konuşun
Tamam, şimdi de WebUSB ile uyumlu bir cihazdan iletişim kurmanın ne kadar kolay olduğuna bakalım. USB bağlantı noktası üzerinden Arduino kartı. Talimatları şu adreste bulabilirsiniz: Çizimlerinizi etkinleştirmek için https://github.com/webusb/arduino adresine gidin.
Merak etmeyin, aşağıda belirtilen tüm WebUSB cihaz yöntemlerini daha sonra ele alacağız bu makaleye göz atın.
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); });
Kullanmakta olduğum WebUSB kitaplığının standart USB seri protokolüne göre hazırlanan ve üreticiler istedikleri uç nokta türlerini ve türlerini oluşturabilir. Kontrol aktarımları özellikle küçük yapılandırma komutlarında otobüse daha fazla öncelik veriliyor ve iyi tanımlanmış bir yapıya sahip.
İşte Arduino panosuna yüklenen çizim.
// Third-party WebUSB Arduino library
#include <WebUSB.h>
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 kitaplığı iki şey var:
- Cihaz, Chrome'un açılış sayfası URL'sini okumasını sağlayan bir WebUSB cihazı gibi çalışır.
- Bu sayfada, varsayılan API'yi geçersiz kılmak için kullanabileceğiniz bir WebUSB Serial API gösterilir.
JavaScript koduna tekrar bakın. Kullanıcının seçtiği device
öğesini aldığımda
device.open()
, USB ile oturum başlatmak için platforma özel tüm adımları çalıştırır
olanak tanır. Ardından mevcut bir USB Yapılandırmasını seçmem gerekiyor.
device.selectConfiguration()
Bir yapılandırmanın,
güç tüketimi ve arayüz sayısı.
Arayüzlerden bahsetmişken
Veriler yalnızca bir arayüze aktarılabildiği için device.claimInterface()
veya
ilişkilendirilen uç noktaları gösterir. Son arama yapılıyor
Arduino cihazını kurmak için device.controlTransferOut()
iletişim kurmak için uygun komutları içerebilir.
device.transferIn()
oradan şuraya toplu aktarım yapar:
ana makinenin toplu veri almaya hazır olduğunu bildirir. Ardından,
söz konusu DataView data
içeren result
nesnesiyle
ayrıştırılması gerekir.
USB'ye aşinaysanız tüm bunlar size tanıdık gelecektir.
Daha fazlasını istiyorum
WebUSB API'si tüm USB aktarım/uç nokta türleriyle etkileşimde bulunmanıza olanak tanır:
- konfigürasyon veya komut göndermek ya da almak için DENETİM aktarımları
parametreleri
controlTransferIn(setup, length)
vecontrolTransferOut(setup, data)
ile işlenir. - Kısa süreli hassas veriler için kullanılan INTERRUPT aktarımları
toplu e-posta yoluyla yapılan aktarımlarla aynı yöntemlerle
transferIn(endpointNumber, length)
vetransferOut(endpointNumber, data)
. - Görüntü ve ses gibi veri akışları için kullanılan ISOCHRONOUS aktarımları,
isochronousTransferIn(endpointNumber, packetLengths)
ve ile ele alındıisochronousTransferOut(endpointNumber, data, packetLengths)
. - Toplu aktarımlar, zamana duyarlı olmayan büyük miktarda veriyi
transferIn(endpointNumber, length)
ile ele alınır ve güvenli bir şekilde işlenir.transferOut(endpointNumber, data)
.
Ayrıca Mike Tsao'nun WebLight projesine USB kontrollü LED cihazlar için iyi bir örnektir. (burada Arduino kullanılmamalıdır). Donanım, yazılım, ve donanım yazılımı.
USB cihazına erişimi iptal etme
Web sitesi, artık ihtiyaç duymadığı bir USB cihaza erişim için izinleri temizleyebilir
USBDevice
örneğinde forget()
çağırarak. Örneğin,
birçok cihazla paylaşılan bir bilgisayarda kullanılan eğitim amaçlı web uygulamasıdır;
kullanıcı tarafından oluşturulan izinlerin birikmesi kötü bir kullanıcı deneyimine neden olmaktadır.
// Voluntarily revoke access to this USB device.
await device.forget();
forget()
, Chrome 101 veya sonraki sürümlerde kullanıma sunulduğundan bu özelliğin
şunlar tarafından desteklenir:
if ("usb" in navigator && "forget" in USBDevice.prototype) {
// forget() is supported.
}
Aktarım boyutuyla ilgili sınırlar
Bazı işletim sistemleri, bir sistem kapsamında yer alabilecek veri miktarına USB işlemleri beklemede. Verilerinizi daha küçük işlemlere bölme ve yalnızca aynı anda birkaç tane göndermek bu sınırlamalardan kaçınmanıza yardımcı olur. Aynı zamanda ve uygulamanızın ilerlemeyi aktarım tamamlandı.
Bir uç noktaya gönderilen birden fazla aktarım her zaman sırayla yürütülür. mümkün olduğunca hızlı ilerlemesini sağlamak için gecikme olabilir. Bir parçanın tamamen iletildiği her seferde kodunuza, yardımcıda belirtildiği şekilde daha fazla veri sağlaması gerektiğini bildirin işlev örneğini aşağıda bulabilirsiniz.
const BULK_TRANSFER_SIZE = 16 * 1024; // 16KB
const MAX_NUMBER_TRANSFERS = 3;
async function sendRawPayload(device, endpointNumber, data) {
let i = 0;
let pendingTransfers = [];
let remainingBytes = data.byteLength;
while (remainingBytes > 0) {
const chunk = data.subarray(
i * BULK_TRANSFER_SIZE,
(i + 1) * BULK_TRANSFER_SIZE
);
// If we've reached max number of transfers, let's wait.
if (pendingTransfers.length == MAX_NUMBER_TRANSFERS) {
await pendingTransfers.shift();
}
// Submit transfers that will be executed in order.
pendingTransfers.push(device.transferOut(endpointNumber, chunk));
remainingBytes -= chunk.byteLength;
i++;
}
// And wait for last remaining transfers to complete.
await Promise.all(pendingTransfers);
}
İpuçları
about://device-log
dahili sayfasını kullanarak Chrome'da USB'de hata ayıklama işlemi daha kolay
Burada, USB cihazıyla ilgili tüm etkinlikleri tek bir yerden görebilirsiniz.
Dahili sayfa about://usb-internals
da kullanışlı bir hale gelir ve
sanal WebUSB cihazların bağlantısını ve bağlantısını kesmeyi simüle eder.
Bu, gerçek donanım olmadan kullanıcı arayüzü testi yaparken faydalıdır.
Çoğu Linux sisteminde, USB cihazları salt okuma izinleriyle
varsayılandır. Chrome'un bir USB cihazı açmasına izin vermek için yeni bir udev eklemeniz gerekir
kuralı ekleyin. /etc/udev/rules.d/50-yourdevicename.rules
adresinde
takip eden içerik:
SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
Örneğin, cihazınız bir Arduino ise [yourdevicevendor]
değeri 2341
olur.
Daha belirli bir kural için ATTR{idProduct}
da eklenebilir. Lütfen
user
, plugdev
grubunun üyesi. Ardından cihazınızı yeniden bağlayın.
Kaynaklar
- Yığın Taşması: https://stackoverflow.com/questions/tagged/webusb
- WebUSB API Spesifikasyonu: http://wicg.github.io/webusb/
- Chrome Özellik Durumu: https://www.chromestatus.com/feature/5651917954875392
- Teknik Özellikler: 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
Hashtag'i kullanarak @ChromiumDev hesabına tweet gönderin
#WebUSB
ve nerede ve nasıl kullandığınızı bize bildirin.
Teşekkür
Bu makaleyi incelediği için Joe Medley'e teşekkür ederiz.