الاتصال بأجهزة HID غير مألوفة

تسمح واجهة WebHID API للمواقع الإلكترونية بالوصول إلى لوحات المفاتيح الإضافية البديلة ولوحات الألعاب غير التقليدية.

François Beaufort
François Beaufort

هناك العديد من الأجهزة التي واجهة بشرية (HID)، مثل الأجهزة لوحات المفاتيح أو وحدات التحكم في الألعاب غير التقليدية والتي تكون حديثة جدًا أو قديمة جدًا أو غير شائعة كثيرًا الوصول إليها من خلال الأنظمة برامج تشغيل الأجهزة. وتحلّ WebHID API هذه المشكلة من خلال توفير لتطبيق منطق خاص بالجهاز في JavaScript.

حالات الاستخدام المقترَحة

يحصل جهاز الواجهة البشرية (HID) على مدخلات من الإنسان أو يوفر إخراجه. أمثلة على الأجهزة تشمل لوحات المفاتيح وأجهزة التأشير (الماوس وشاشات اللمس وغيرها) ولوحات الألعاب. يتيح بروتوكول HID إمكانية الوصول إلى هذه الأجهزة على أجهزة الكمبيوتر المكتبي. أجهزة الكمبيوتر التي تستخدم برامج تشغيل أنظمة التشغيل. منصة الويب متوافقة مع أجهزة HID من خلال الاعتماد على هذه السائقين

تكون عدم القدرة على الوصول إلى أجهزة HID غير المألوفة مؤلمة بشكل خاص عندما بالنسبة إلى لوحات المفاتيح الإضافية البديلة (مثل Elgato Stream Deck وJabra) سمّاعات الرأس ومفاتيح X) وأدوات تحكّم فريدة في الألعاب. لوحات ألعاب مصممة للكمبيوتر المكتبي غالبًا ما يستخدمون واجهة بشرية (HID) لإدخالات لوحة الألعاب (الأزرار وأذرع التحكّم والمشغِّلات) والمخرجات. (أضواء LED وطقطقة). بيانات المدخلات والمخرجات في لوحة الألعاب غير جيدة. غالبًا ما تتطلب متصفحات الويب القياسية منطقًا مخصصًا لأجهزة معينة. وهذا أمر غير مستدام ويؤدي إلى ضعف الدعم للأشخاص الأكبر سنًا الأجهزة غير الشائعة. كما يتسبب في اعتماد المتصفح على الأخطاء في السلوك أجهزة محددة.

المصطلحات

تتألف أجهزة HID من مفهومَين أساسيَين: التقارير وأدوات وصف التقارير. التقارير هي البيانات التي يتم تبادلها بين جهاز وبرنامج عميل. يصف واصف التقرير تنسيق البيانات التي يستخدمها الجهاز والدعم.

جهاز الواجهة البشرية (HID) هو نوع من الأجهزة التي تتلقى إدخالات من ويوفر إخراجًا للبشر. كما تشير إلى بروتوكول HID، وهو معيار هو الاتصال ثنائي الاتجاه بين المضيف وجهاز مصمم وتبسيط إجراء التثبيت. تم في الأصل تطوير بروتوكول HID لأجهزة USB، ولكن تم تنفيذه على العديد من البروتوكولات الأخرى، بما في ذلك البلوتوث.

تتبادل التطبيقات وأجهزة الواجهة البشرية (HID) البيانات الثنائية من خلال ثلاثة أنواع من التقارير:

نوع التقرير الوصف
تقرير الإدخال البيانات التي يتم إرسالها من الجهاز إلى التطبيق (على سبيل المثال، يتم الضغط على زر).
تقرير المخرجات البيانات التي يتم إرسالها من التطبيق إلى الجهاز (مثل طلب تشغيل الإضاءة الخلفية للوحة المفاتيح)
تقرير الميزات البيانات التي قد يتم إرسالها في أي من الاتجاهين. ويكون التنسيق خاصًا بالجهاز.

يصف واصف التقرير التنسيق الثنائي للتقارير المدعومة من الخاص بك. ويكون هيكلها هرميًا ويمكنها تجميع التقارير معًا باعتبارها تقارير المجموعات ضمن المجموعة ذات المستوى الأعلى. التنسيق للواصف هو المحددة من خلال مواصفات HID.

استخدام الواجهة البشرية (HID) هو قيمة رقمية تشير إلى إدخال أو إخراج موحّد. تسمح قيم الاستخدام للجهاز بوصف الاستخدام المقصود للجهاز الغرض من كل حقل في تقاريره. فعلى سبيل المثال، يُحدَّد واحد لليسار وزر الماوس. كما يتم تنظيم الاستخدامات في صفحات استخدام، والتي توفر إشارة إلى الفئة عالية المستوى للجهاز أو التقرير.

استخدام WebHID API

رصد الميزات

للتحقّق مما إذا كانت واجهة برمجة التطبيقات WebHID API متوافقة، يمكنك استخدام:

if ("hid" in navigator) {
  // The WebHID API is supported.
}

فتح اتصال HID

إنّ واجهة WebHID API غير متزامنة من حيث التصميم لمنع واجهة مستخدم الموقع الإلكتروني من المنع عند انتظار الإدخال. هذه الخطوة مهمة لأنّه يمكن تلقّي بيانات HID. في أي وقت، الأمر الذي يتطلب طريقة للاستماع إليها.

لفتح اتصال واجهة بشرية (HID)، يجب أولاً الوصول إلى عنصر HIDDevice. لهذا، يمكنك مطالبة المستخدم باختيار جهاز من خلال يمكنك navigator.hid.requestDevice() أو اختيار صورة من navigator.hid.getDevices(). الذي يعرض قائمة بالأجهزة التي حصل الموقع الإلكتروني على إذن بالوصول إليها مسبقًا.

تستخدم الدالة navigator.hid.requestDevice() كائنًا إلزاميًا تحدد عوامل التصفية. تُستخدم هذه البيانات لمطابقة أي جهاز متصل بمورِّد USB معرّف (vendorId) ومعرّف منتج USB (productId) وصفحة استخدام قيمة (usagePage)، وقيمة استخدام (usage). يمكنك الحصول عليها من مستودع معرّفات USB ومستند جداول استخدام HID.

إنّ كائنات HIDDevice المتعددة التي تعرضها هذه الدالة تمثل عدة كائنات واجهات HID على الجهاز الفعلي نفسه

// Filter on devices with the Nintendo Switch Joy-Con USB Vendor/Product IDs.
const filters = [
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2006 // Joy-Con Left
  },
  {
    vendorId: 0x057e, // Nintendo Co., Ltd
    productId: 0x2007 // Joy-Con Right
  }
];

// Prompt user to select a Joy-Con device.
const [device] = await navigator.hid.requestDevice({ filters });
// Get all devices the user has previously granted the website access to.
const devices = await navigator.hid.getDevices();
لقطة شاشة لإشعار على جهاز HID على موقع إلكتروني
طلب من المستخدم لاختيار Nintendo Switch Joy-Con.

يمكنك أيضًا استخدام مفتاح exclusionFilters الاختياري في navigator.hid.requestDevice() لاستبعاد بعض الأجهزة من أداة اختيار المتصفّحات. المعروفة بأعطالها على سبيل المثال.

// Request access to a device with vendor ID 0xABCD. The device must also have
// a collection with usage page Consumer (0x000C) and usage ID Consumer
// Control (0x0001). The device with product ID 0x1234 is malfunctioning.
const [device] = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0xabcd, usagePage: 0x000c, usage: 0x0001 }],
  exclusionFilters: [{ vendorId: 0xabcd, productId: 0x1234 }],
});

عنصر HIDDevice يحتوي على مورِّد USB ومعرّفات المنتجات للجهاز الهوية. يتمّ إعداد السمة collections باستخدام تدرّج هرمي. وصف لتنسيقات تقارير الجهاز.

for (let collection of device.collections) {
  // An HID collection includes usage, usage page, reports, and subcollections.
  console.log(`Usage: ${collection.usage}`);
  console.log(`Usage page: ${collection.usagePage}`);

  for (let inputReport of collection.inputReports) {
    console.log(`Input report: ${inputReport.reportId}`);
    // Loop through inputReport.items
  }

  for (let outputReport of collection.outputReports) {
    console.log(`Output report: ${outputReport.reportId}`);
    // Loop through outputReport.items
  }

  for (let featureReport of collection.featureReports) {
    console.log(`Feature report: ${featureReport.reportId}`);
    // Loop through featureReport.items
  }

  // Loop through subcollections with collection.children
}

يتم تلقائيًا عرض أجهزة HIDDevice في حالة "مغلقة". ويجب أن يكون تم فتحها من خلال الاتصال بـ open() قبل إرسال البيانات أو استلامها.

// Wait for the HID connection to open before sending/receiving data.
await device.open();

تلقّي تقارير الإدخال

بعد إنشاء اتصال HID، يمكنك التعامل مع مصادر الإدخال الواردة. عن طريق الاستماع إلى أحداث "inputreport" من الجهاز. تِلْكَ الْأَحْدَاثْ يحتوي على بيانات HID ككائن DataView (data)، وجهاز HID الذي ينتمي إليه إلى (device)، ومعرّف تقرير 8 بت المرتبط بتقرير الإدخال (reportId).

صورة لجهاز nintendo Switch باللونَين الأحمر والأزرق
أجهزة Nintendo Switch Joy-Con

استكمالاً للمثال السابق، توضح لك التعليمات البرمجية أدناه كيفية اكتشاف الزر الذي ضغط عليه المستخدم على جهاز Joy-Conright حتى تتمكن من نأمل تجربتها في المنزل.

device.addEventListener("inputreport", event => {
  const { data, device, reportId } = event;

  // Handle only the Joy-Con Right device and a specific report ID.
  if (device.productId !== 0x2007 && reportId !== 0x3f) return;

  const value = data.getUint8(0);
  if (value === 0) return;

  const someButtons = { 1: "A", 2: "X", 4: "B", 8: "Y" };
  console.log(`User pressed button ${someButtons[value]}.`);
});

إرسال تقارير النتائج

لإرسال تقرير إخراج إلى جهاز HID، عليك تمرير رقم تعريف التقرير 8 بت المرتبط مع تقرير الإخراج (reportId) ووحدات البايت باعتبارها BufferSource (data) device.sendReport() يتم حلّ المشكلة التي تم إرجاعها بعد تقديم البلاغ. تم إرسالها. إذا كان جهاز HID لا يستخدم أرقام تعريف التقارير، اضبط السمة reportId على 0.

ينطبق المثال أدناه على جهاز Joy-Con ويوضح لك كيفية إعداده تقارير الإخراج.

// First, send a command to enable vibration.
// Magical bytes come from https://github.com/mzyy94/joycon-toolweb
const enableVibrationData = [1, 0, 1, 64, 64, 0, 1, 64, 64, 0x48, 0x01];
await device.sendReport(0x01, new Uint8Array(enableVibrationData));

// Then, send a command to make the Joy-Con device rumble.
// Actual bytes are available in the sample below.
const rumbleData = [ /* ... */ ];
await device.sendReport(0x10, new Uint8Array(rumbleData));

إرسال تقارير الميزات وتلقّيها

تقارير الميزات هي النوع الوحيد من تقارير بيانات الواجهة البشرية (HID) الذي يمكن أن ينتقل في كلتا الاتجاهات. تسمح لأجهزة HID وتطبيقاتها بتبادل البيانات غير الموحّدة بيانات HID على عكس تقارير الإدخال والمخرجات، لا يتم تلقي تقارير الميزات أو يرسلها التطبيق بشكل منتظم.

صورة جهاز كمبيوتر محمول باللونين الأسود والفضي
لوحة مفاتيح للكمبيوتر المحمول

لإرسال تقرير ميزة إلى جهاز واجهة بشرية (HID)، عليك تمرير رقم تعريف التقرير 8 بت المرتبط مع تقرير الميزة (reportId) ووحدات البايت باعتبارها BufferSource (data) device.sendFeatureReport() تتم معالجة وعد إرجاع المشتريات بعد أن يتم الإبلاغ عن . إذا كان جهاز HID لا يستخدم أرقام تعريف التقارير، اضبط السمة reportId على 0.

يوضح المثال التالي استخدام تقارير الميزات من خلال توضيح كيفية طلب جهاز إضاءة خلفية للوحة مفاتيح Apple، وفتحه وجعله يرمش.

const waitFor = duration => new Promise(r => setTimeout(r, duration));

// Prompt user to select an Apple Keyboard Backlight device.
const [device] = await navigator.hid.requestDevice({
  filters: [{ vendorId: 0x05ac, usage: 0x0f, usagePage: 0xff00 }]
});

// Wait for the HID connection to open.
await device.open();

// Blink!
const reportId = 1;
for (let i = 0; i < 10; i++) {
  // Turn off
  await device.sendFeatureReport(reportId, Uint32Array.from([0, 0]));
  await waitFor(100);
  // Turn on
  await device.sendFeatureReport(reportId, Uint32Array.from([512, 0]));
  await waitFor(100);
}

لتلقّي تقرير ميزة من جهاز HID، عليك ضبط رقم تعريف التقرير 8 بت. المرتبطة بتقرير الميزة (reportId) من أجل device.receiveFeatureReport() يتم حل الوعد المرتجع من خلال العنصر DataView الذي يحتوي على محتوى تقرير الميزات. في حال وجود جهاز HID الجهاز لا يستخدم أرقام تعريف التقارير، اضبط reportId على 0.

// Request feature report.
const dataView = await device.receiveFeatureReport(/* reportId= */ 1);

// Read feature report contents with dataView.getInt8(), getUint8(), etc...

الاستماع إلى الاتصال وانقطاع الاتصال

عندما يتم منح الموقع الإلكتروني إذنًا بالوصول إلى جهاز HID، يمكنه ستتلقّى أحداث الاتصال وانقطاع الاتصال عن طريق الاستماع إلى "connect" و"disconnect" حدث.

navigator.hid.addEventListener("connect", event => {
  // Automatically open event.device or warn user a device is available.
});

navigator.hid.addEventListener("disconnect", event => {
  // Remove |event.device| from the UI.
});

إبطال إمكانية الوصول إلى جهاز واجهة بشرية (HID)

يمكن للموقع الإلكتروني التخلص من أذونات الوصول إلى جهاز الواجهة البشرية (HID) الذي لم يعُد مهتم بالاحتفاظ بها من خلال طلب الرقم forget() على الجهاز الافتراضي HIDDevice. بالنسبة لأحد تطبيقات الويب التعليمية المستخدمة على جهاز كمبيوتر مشترك مع العديد من الأجهزة، فإن عددًا كبيرًا من الأذونات المتراكمة من إنشاء المستخدمين يؤدي إلى تجربة المستخدم.

سيؤدي الاتصال بالرقم forget() على جهاز HIDDevice واحد إلى إبطال إمكانية الوصول إلى جميع جهات الاتصال. واجهات HID على الجهاز الفعلي نفسه.

// Voluntarily revoke access to this HID device.
await device.forget();

بما أنّ forget() يتوفّر في Chrome 100 أو إصدار أحدث، يُرجى التحقّق ممّا إذا كانت هذه الميزة متاحة متوافقة مع ما يلي:

if ("hid" in navigator && "forget" in HIDDevice.prototype) {
  // forget() is supported.
}

نصائح لمطوّري البرامج

يمكن بسهولة تصحيح أخطاء HID في Chrome باستخدام الصفحة الداخلية about://device-log. يمكنك من خلاله الاطّلاع على جميع الأحداث ذات الصلة بجهاز HID وUSB في مكان واحد.

لقطة شاشة للصفحة الداخلية لتصحيح أخطاء HID.
صفحة داخلية في Chrome لتصحيح أخطاء HID

يمكنك الاطّلاع على مستكشف واجهة بشرية HID لتفريغ جهاز HID. المعلومات إلى تنسيق يسهل على الإنسان قراءته. يحدد من قيم الاستخدام إلى أسماء كل استخدام أجهزة HID

في معظم أنظمة Linux، يتم ربط أجهزة الواجهة البشرية (HID) بأذونات القراءة فقط من خلال الافتراضي. للسماح لمتصفِّح Chrome بفتح جهاز HID، عليك إضافة أداة udev جديدة. . أنشئ ملفًا على /etc/udev/rules.d/50-yourdevicename.rules باستخدام المحتوى التالي:

KERNEL=="hidraw*", ATTRS{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

في السطر أعلاه، تكون قيمة [yourdevicevendor] هي 057e إذا كان جهازك من فئة Nintendo Switch. Joy-Con على سبيل المثال. يمكن أيضًا إضافة ATTRS{idProduct} لعنوان URL أكثر تحديدًا. قاعدة البيانات. احرص على أن يكون user عضوًا في مجموعة plugdev. بعد ذلك، إعادة توصيل جهازك.

دعم المتصفح

تتوفّر واجهة برمجة التطبيقات WebHID API على جميع الأنظمة الأساسية لأجهزة كمبيوتر سطح المكتب (ChromeOS وLinux وmacOS وWindows) في Chrome 89.

إصدارات تجريبية

يمكن الاطّلاع على بعض إصدارات WebHID التجريبية على الرابط web.dev/hid-examples. ألقِ نظرة!

الأمان والخصوصية

صمّم مؤلفو المواصفات واجهة برمجة التطبيقات WebHID API ونفّذوها باستخدام المحددة في التحكُّم في الوصول إلى ميزات النظام الأساسي للويب الفعّالة بما في ذلك تحكُّم المستخدم والشفافية وتسهيل الاستخدام. القدرة على استخدام هذه تكون واجهة برمجة التطبيقات متوقفة بشكل أساسي من خلال نموذج أذونات يمنح إذن الوصول إلى مستخدم واحد فقط جهاز HID في كل مرة استجابةً لمطالبة المستخدم، يجب أن يفعّل المستخدم الخطوات لاختيار جهاز واجهة بشرية محدد.

لفهم الإيجابيات والسلبيات المتعلّقة بالأمان، راجِع قسم الأمان والخصوصية قسم الاعتبارات ضمن مواصفات WebHID

علاوة على ذلك، يفحص Chrome استخدام كل مجموعة ذات مستوى أعلى وما إذا مجموعة ذات مستوى أعلى لها استخدام محمي (على سبيل المثال، لوحة المفاتيح العامة والماوس)، ثم لن يتمكن أي موقع ويب من إرسال وتلقي أي تقارير محددة في الأولية. القائمة الكاملة للاستخدامات المحمية متاحة للجميع.

يُرجى ملاحظة أنّ أجهزة الواجهة البشرية (HID) الحساسة للأمان (مثل أجهزة FIDO HID التي تُستخدم مصادقة أقوى) محظورة أيضًا في Chrome. يمكنك الاطّلاع على قائمة حظر أجهزة USB و ملفات قائمة حظر أجهزة HID

ملاحظات

يودّ فريق Chrome معرفة رأيك وخبراتك في WebHID API

أخبِرنا عن تصميم واجهة برمجة التطبيقات

هل هناك أي مشكلة في واجهة برمجة التطبيقات لا تعمل كما هو متوقع؟ أم أن هناك الطرق المفقودة أو الخصائص التي تحتاجها لتنفيذ فكرتك؟

يُرجى الإبلاغ عن مشكلة في المواصفات في مستودع WebHID API GitHub أو إضافة أفكارك. بمشكلة حالية.

الإبلاغ عن مشكلة في التنفيذ

هل واجهت مشكلة في التنفيذ في Chrome؟ أم أن التنفيذ عن المواصفات؟

يمكنك الاطّلاع على كيفية الإبلاغ عن أخطاء WebHID. تأكد من تضمين أكبر قدر قدر الإمكان، وتقديم إرشادات بسيطة لإعادة إنتاج الخطأ، تم ضبط المكوّنات على Blink>HID. يعمل الخطأ بشكل رائع مشاركة عمليات إعادة الإنتاج السريعة والسهلة.

إظهار الدعم

هل تخطّط لاستخدام واجهة برمجة تطبيقات WebHID API؟ يساعد دعمك العام متصفّح Chrome أولويات الفريق للميزات وتوضح لموردي المتصفح الآخرين مدى أهمية ودعمه.

إرسال تغريدة إلى @ChromiumDev باستخدام علامة التصنيف #WebHID وإبلاغنا بذلك ومكان وكيفية استخدامها.

روابط مفيدة

شكر وتقدير

نشكر مات رينولدز وجو ميدلي على مراجعاتهما لهذه المقالة. صورة لجهاز Nintendo Switch باللونَين الأحمر والأزرق من تصميم سارة كورفيس، وجهاز كمبيوتر محمول باللونَين الأسود والفضي صورة فوتوغرافية من Athul Cyriac Ajay على موقع Un تتوفر.