किसी सीरियल पोर्ट से पढ़ें और उस पर लिखें

Web Serial API, वेबसाइटों को सीरियल डिवाइसों से संपर्क करने की अनुमति देता है.

François Beaufort
François Beaufort

Web Serial API क्या है?

सीरियल पोर्ट, दो-तरफ़ा कम्यूनिकेशन इंटरफ़ेस होता है. इसकी मदद से, बाइट बाइट बाइट डेटा भेजा और पाया जा सकता है.

Web Serial API, वेबसाइटों को JavaScript वाले किसी सीरियल डिवाइस से पढ़ने और उस पर लिखने का तरीका मुहैया कराता है. सीरियल डिवाइस, उपयोगकर्ता के सिस्टम पर मौजूद सीरियल पोर्ट के ज़रिए या हटाए जा सकने वाले यूएसबी और ब्लूटूथ डिवाइसों से कनेक्ट होते हैं, जो सीरियल पोर्ट को एम्युलेट करते हैं.

दूसरे शब्दों में, Web Serial API, वेबसाइटों को माइक्रोकंट्रोलर और 3D प्रिंटर जैसे सीरियल डिवाइस से संपर्क करने की अनुमति देकर, वेब और फ़िज़िकल दुनिया को आपस में जोड़ता है.

यह एपीआई WebUSB का भी अच्छा साथी है, क्योंकि ऑपरेटिंग सिस्टम में ऐप्लिकेशन को कुछ सीरियल पोर्ट के साथ इंटरैक्ट करने के लिए, लो-लेवल के यूएसबी एपीआई की जगह उनके हाई-लेवल के सीरियल एपीआई की ज़रूरत होती है.

इस्तेमाल के सुझाए गए उदाहरण

शिक्षा, शौकिया, और औद्योगिक सेक्टर में, उपयोगकर्ता सहायक डिवाइसों को अपने कंप्यूटर से कनेक्ट करते हैं. ये डिवाइस अक्सर माइक्रोकंट्रोलर से कंट्रोल किए जाते हैं. ये डिवाइस ऐसे सीरियल कनेक्शन से कंट्रोल करते हैं जिसका इस्तेमाल कस्टम सॉफ़्टवेयर में किया जाता है. इन डिवाइसों को कंट्रोल करने वाले कुछ कस्टम सॉफ़्टवेयर, वेब टेक्नोलॉजी से बनाए गए हैं:

कुछ मामलों में, वेबसाइटें, एजेंट ऐप्लिकेशन के ज़रिए डिवाइस से इंटरैक्ट करती हैं, जिसे लोगों ने मैन्युअल तौर पर इंस्टॉल किया है. वहीं, ऐप्लिकेशन को Electron जैसे फ़्रेमवर्क की मदद से पैकेज वाले ऐप्लिकेशन में डिलीवर किया जाता है. दूसरे मामलों में, उपयोगकर्ता को एक और चरण पूरा करना पड़ता है, जैसे कि किसी कंपाइल किए गए ऐप्लिकेशन को यूएसबी फ़्लैश ड्राइव से डिवाइस पर कॉपी करना.

इन सभी मामलों में, वेबसाइट और उसे कंट्रोल करने वाले डिवाइस के बीच सीधे संपर्क की सुविधा देकर, उपयोगकर्ता अनुभव को बेहतर बनाया जाएगा.

मौजूदा स्थिति

चरण स्थिति
1. जानकारी बनाएं पूरा हुआ
2. खास जानकारी का शुरुआती ड्राफ़्ट बनाएं पूरा हुआ
3. लोगों की राय जानें और डिज़ाइन को बेहतर बनाएं पूरा हुआ
4. ऑरिजिन ट्रायल पूरा हुआ
5. लॉन्च करना पूरा हुआ

Web Serial API का इस्तेमाल करना

सुविधा की पहचान करने की सुविधा

Web Serial API काम करता है या नहीं, यह देखने के लिए इनका इस्तेमाल करें:

if ("serial" in navigator) {
  // The Web Serial API is supported.
}

सीरियल पोर्ट खोलें

Web Serial API को डिज़ाइन के हिसाब से एसिंक्रोनस है. यह इनपुट का इंतज़ार करते समय वेबसाइट यूज़र इंटरफ़ेस (यूआई) को ब्लॉक होने से रोकता है. यह इसलिए अहम है, क्योंकि सीरियल डेटा कभी भी पाया जा सकता है और इसे सुनने के लिए किसी तरीके की ज़रूरत होती है.

सीरियल पोर्ट खोलने के लिए, पहले SerialPort ऑब्जेक्ट को ऐक्सेस करें. इसके लिए, उपयोगकर्ता से एक सीरियल पोर्ट चुनने का प्रॉम्प्ट किया जा सकता है. इसके लिए, उपयोगकर्ता के जेस्चर (छूना) या माउस पर क्लिक करने जैसे जेस्चर के जवाब में, navigator.serial.requestPort() को कॉल करके उपयोगकर्ता को एक सीरियल पोर्ट चुनने का निर्देश दिया जा सकता है. इसके अलावा, navigator.serial.getPorts() में से कोई एक चुना जा सकता है, जो वेबसाइट को ऐक्सेस दिए गए सीरियल पोर्ट की सूची दिखाता है.

document.querySelector('button').addEventListener('click', async () => {
  // Prompt user to select any serial port.
  const port = await navigator.serial.requestPort();
});
// Get all serial ports the user has previously granted the website access to.
const ports = await navigator.serial.getPorts();

navigator.serial.requestPort() फ़ंक्शन, फ़िल्टर के बारे में बताने वाला एक वैकल्पिक ऑब्जेक्ट लिटरल लेता है. इनका इस्तेमाल यूएसबी से कनेक्ट किए गए किसी भी सीरियल डिवाइस को एक ज़रूरी यूएसबी वेंडर (usbVendorId) और वैकल्पिक यूएसबी प्रॉडक्ट आइडेंटिफ़ायर (usbProductId) से करने के लिए किया जाता है.

// Filter on devices with the Arduino Uno USB Vendor/Product IDs.
const filters = [
  { usbVendorId: 0x2341, usbProductId: 0x0043 },
  { usbVendorId: 0x2341, usbProductId: 0x0001 }
];

// Prompt user to select an Arduino Uno device.
const port = await navigator.serial.requestPort({ filters });

const { usbProductId, usbVendorId } = port.getInfo();
वेबसाइट पर सीरियल पोर्ट के अनुरोध का स्क्रीनशॉट
बीबीसी माइक्रो:बिट चुनने के लिए उपयोगकर्ता का अनुरोध

requestPort() को कॉल करने पर, उपयोगकर्ता को डिवाइस चुनने के लिए कहा जाता है और SerialPort ऑब्जेक्ट दिखाया जाता है. SerialPort ऑब्जेक्ट मिलने के बाद, port.open() को मनचाहे बॉड रेट के साथ कॉल करने से सीरियल पोर्ट खुल जाएगा. baudRate शब्दकोश का सदस्य यह बताता है कि किसी सीरियल लाइन पर डेटा कितनी तेज़ी से भेजा जाता है. इसे बिट प्रति सेकंड (बीपीएस) की इकाइयों में दिखाया जाता है. सही वैल्यू के लिए अपने डिवाइस के दस्तावेज़ देखें, क्योंकि अगर इसे गलत तरीके से तय किया गया है, तो आपके भेजे और पाए गए सभी डेटा बेमतलब के होंगे. सीरियल पोर्ट को एम्युलेट करने वाले कुछ यूएसबी और ब्लूटूथ डिवाइसों के लिए, इस वैल्यू को किसी भी वैल्यू पर सुरक्षित तरीके से सेट किया जा सकता है. ऐसा इसलिए, क्योंकि एम्युलेटर इसे अनदेखा कर देता है.

// Prompt user to select any serial port.
const port = await navigator.serial.requestPort();

// Wait for the serial port to open.
await port.open({ baudRate: 9600 });

सीरियल पोर्ट को खोलते समय, नीचे दिया गया कोई विकल्प भी चुना जा सकता है. ये विकल्प ज़रूरी नहीं हैं और इनकी डिफ़ॉल्ट वैल्यू आसानी से उपलब्ध होती हैं.

  • dataBits: हर फ़्रेम के लिए डेटा बिट की संख्या (7 या 8).
  • stopBits: फ़्रेम के आखिर में स्टॉप बिट की संख्या (1 या 2).
  • parity: पैरिटी मोड ("none", "even" या "odd").
  • bufferSize: बनाए जाने वाले रीड और राइट बफ़र का साइज़ (16 एमबी से कम होना चाहिए).
  • flowControl: फ़्लो कंट्रोल मोड ("none" या "hardware").

किसी सीरियल पोर्ट से पढ़ें

Web Serial API में इनपुट और आउटपुट स्ट्रीम, Streams API मैनेज करते हैं.

सीरियल पोर्ट कनेक्शन बनने के बाद, SerialPort ऑब्जेक्ट की readable और writable प्रॉपर्टी, ReadableStream और WritableStream दिखाती हैं. उनका इस्तेमाल सीरियल डिवाइस से डेटा पाने और उस पर डेटा भेजने के लिए किया जाएगा. दोनों डेटा ट्रांसफ़र के लिए Uint8Array इंस्टेंस का इस्तेमाल करते हैं.

जब सीरियल डिवाइस से नया डेटा मिलता है, तो port.readable.getReader().read() एसिंक्रोनस तरीके से दो प्रॉपर्टी दिखाता है: value और done बूलियन. अगर done सही है, तो सीरियल पोर्ट को बंद कर दिया गया है या कोई और डेटा नहीं आ रहा है. port.readable.getReader() को कॉल करने पर एक रीडर बन जाता है और readable को उस पर लॉक कर दिया जाता है. readable के लॉक होने पर, सीरियल पोर्ट को बंद नहीं किया जा सकता.

const reader = port.readable.getReader();

// Listen to data coming from the serial device.
while (true) {
  const { value, done } = await reader.read();
  if (done) {
    // Allow the serial port to be closed later.
    reader.releaseLock();
    break;
  }
  // value is a Uint8Array.
  console.log(value);
}

कुछ स्थितियों में ऐसा हो सकता है कि सीरियल पोर्ट को पढ़ने में कोई गड़बड़ी न हो. जैसे, बफ़र ओवरफ़्लो, फ़्रेमिंग की गड़बड़ियां या समानता से जुड़ी गड़बड़ियां. इन्हें अपवाद के तौर पर डाला जाता है. इन्हें port.readable की जांच करने वाले पिछले लूप के ऊपर दूसरा लूप जोड़कर पकड़ा जा सकता है. यह काम करता है, क्योंकि जब तक गड़बड़ियां ठीक नहीं होती हैं, तब तक अपने-आप एक नया ReadableStream बन जाता है. अगर कोई गंभीर गड़बड़ी होती है, जैसे कि सीरियल डिवाइस को हटा दिया जाना, तो port.readable शून्य हो जाता है.

while (port.readable) {
  const reader = port.readable.getReader();

  try {
    while (true) {
      const { value, done } = await reader.read();
      if (done) {
        // Allow the serial port to be closed later.
        reader.releaseLock();
        break;
      }
      if (value) {
        console.log(value);
      }
    }
  } catch (error) {
    // TODO: Handle non-fatal read error.
  }
}

अगर सीरियल डिवाइस फिर से मैसेज भेजता है, तो port.readable को TextDecoderStream से पाइप किया जा सकता है, जैसा कि यहां दिखाया गया है. TextDecoderStream, एक ट्रांसफ़ॉर्म स्ट्रीम है, जो सभी Uint8Array हिस्सों को इकट्ठा करके, स्ट्रिंग में बदल देती है.

const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable.getReader();

// Listen to data coming from the serial device.
while (true) {
  const { value, done } = await reader.read();
  if (done) {
    // Allow the serial port to be closed later.
    reader.releaseLock();
    break;
  }
  // value is a string.
  console.log(value);
}

स्ट्रीम से पढ़ते समय, "अपना बफ़र लाएं" रीडर का इस्तेमाल करके, यह तय किया जा सकता है कि मेमोरी को कैसे बांटा जाए. ReadableStreamBYOBReader इंटरफ़ेस पाने के लिए, port.readable.getReader({ mode: "byob" }) को कॉल करें और read() को कॉल करते समय अपना ArrayBuffer दें. ध्यान रखें कि Web Serial API, Chrome 106 या इसके बाद के वर्शन में यह सुविधा देता है.

try {
  const reader = port.readable.getReader({ mode: "byob" });
  // Call reader.read() to read data into a buffer...
} catch (error) {
  if (error instanceof TypeError) {
    // BYOB readers are not supported.
    // Fallback to port.readable.getReader()...
  }
}

value.buffer के बफ़र का फिर से इस्तेमाल करने का तरीका जानने के लिए, यहां एक उदाहरण दिया गया है:

const bufferSize = 1024; // 1kB
let buffer = new ArrayBuffer(bufferSize);

// Set `bufferSize` on open() to at least the size of the buffer.
await port.open({ baudRate: 9600, bufferSize });

const reader = port.readable.getReader({ mode: "byob" });
while (true) {
  const { value, done } = await reader.read(new Uint8Array(buffer));
  if (done) {
    break;
  }
  buffer = value.buffer;
  // Handle `value`.
}

यहां सीरियल पोर्ट से किसी तय संख्या के डेटा को पढ़ने का तरीका बताया गया है:

async function readInto(reader, buffer) {
  let offset = 0;
  while (offset < buffer.byteLength) {
    const { value, done } = await reader.read(
      new Uint8Array(buffer, offset)
    );
    if (done) {
      break;
    }
    buffer = value.buffer;
    offset += value.byteLength;
  }
  return buffer;
}

const reader = port.readable.getReader({ mode: "byob" });
let buffer = new ArrayBuffer(512);
// Read the first 512 bytes.
buffer = await readInto(reader, buffer);
// Then read the next 512 bytes.
buffer = await readInto(reader, buffer);

किसी सीरियल पोर्ट पर लिखें

किसी सीरियल डिवाइस पर डेटा भेजने के लिए, डेटा को port.writable.getWriter().write() पर पास करें. सीरियल पोर्ट को बाद में बंद करने के लिए, port.writable.getWriter() पर releaseLock() को कॉल करना ज़रूरी है.

const writer = port.writable.getWriter();

const data = new Uint8Array([104, 101, 108, 108, 111]); // hello
await writer.write(data);


// Allow the serial port to be closed later.
writer.releaseLock();

यहां बताए गए तरीके से, port.writable पर पाइप किए गए TextEncoderStream की मदद से डिवाइस पर टेक्स्ट भेजें.

const textEncoder = new TextEncoderStream();
const writableStreamClosed = textEncoder.readable.pipeTo(port.writable);

const writer = textEncoder.writable.getWriter();

await writer.write("hello");

सीरियल पोर्ट को बंद करें

अगर readable और writable के सदस्यों को अनलॉक किया गया है, तो port.close() सीरियल पोर्ट को बंद कर देता है. इसका मतलब है कि releaseLock() को उनके रीडर और राइटर के लिए कॉल किया गया है.

await port.close();

हालांकि, लूप का इस्तेमाल करके सीरियल डिवाइस से लगातार डेटा पढ़ते समय, port.readable हमेशा लॉक रहेगा, जब तक कि कोई गड़बड़ी न हो. ऐसे मामले में, reader.cancel() को कॉल करने पर, reader.read() को { value: undefined, done: true } से तुरंत कार्रवाई करनी होगी. इससे लूप, reader.releaseLock() को कॉल कर पाएगा.

// Without transform streams.

let keepReading = true;
let reader;

async function readUntilClosed() {
  while (port.readable && keepReading) {
    reader = port.readable.getReader();
    try {
      while (true) {
        const { value, done } = await reader.read();
        if (done) {
          // reader.cancel() has been called.
          break;
        }
        // value is a Uint8Array.
        console.log(value);
      }
    } catch (error) {
      // Handle error...
    } finally {
      // Allow the serial port to be closed later.
      reader.releaseLock();
    }
  }

  await port.close();
}

const closedPromise = readUntilClosed();

document.querySelector('button').addEventListener('click', async () => {
  // User clicked a button to close the serial port.
  keepReading = false;
  // Force reader.read() to resolve immediately and subsequently
  // call reader.releaseLock() in the loop example above.
  reader.cancel();
  await closedPromise;
});

स्ट्रीम को बदलें का इस्तेमाल करते समय, सीरियल पोर्ट को बंद करना ज़्यादा मुश्किल होता है. पहले की तरह reader.cancel() पर कॉल करें. इसके बाद, writer.close() और port.close() पर कॉल करें. ऐसा करने से, स्ट्रीम को पहले से मौजूद सीरियल पोर्ट में बदलाव करके गड़बड़ियों को दूर किया जाता है. गड़बड़ी लागू नहीं होती, इसलिए port.readable और port.writable के अनलॉक होने का पता लगाने के लिए, आपको पहले बनाए गए readableStreamClosed और writableStreamClosed प्रॉमिस का इस्तेमाल करना होगा. reader को रद्द करने से स्ट्रीम रद्द हो जाती है. इसलिए, आपको गड़बड़ी के नतीजे को देखना और उसे अनदेखा करना होगा.

// With transform streams.

const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable.getReader();

// Listen to data coming from the serial device.
while (true) {
  const { value, done } = await reader.read();
  if (done) {
    reader.releaseLock();
    break;
  }
  // value is a string.
  console.log(value);
}

const textEncoder = new TextEncoderStream();
const writableStreamClosed = textEncoder.readable.pipeTo(port.writable);

reader.cancel();
await readableStreamClosed.catch(() => { /* Ignore the error */ });

writer.close();
await writableStreamClosed;

await port.close();

कनेक्शन और डिसकनेक्ट होने की आवाज़ सुनें

अगर यूएसबी डिवाइस से सीरियल पोर्ट दिया गया है, तो वह डिवाइस कनेक्ट या सिस्टम से डिसकनेक्ट हो सकता है. वेबसाइट को सीरियल पोर्ट को ऐक्सेस करने की अनुमति मिलने पर, उसे connect और disconnect इवेंट की निगरानी करनी चाहिए.

navigator.serial.addEventListener("connect", (event) => {
  // TODO: Automatically open event.target or warn user a port is available.
});

navigator.serial.addEventListener("disconnect", (event) => {
  // TODO: Remove |event.target| from the UI.
  // If the serial port was opened, a stream error would be observed as well.
});

सिग्नल मैनेज करना

सीरियल पोर्ट कनेक्शन बनने के बाद, डिवाइस की पहचान और फ़्लो कंट्रोल के लिए, सीरियल पोर्ट से दिखाए गए सिग्नल के लिए साफ़ तौर पर क्वेरी की जा सकती है और उन्हें सेट किया जा सकता है. इन सिग्नल को बूलियन वैल्यू के तौर पर तय किया जाता है. उदाहरण के लिए, अगर डेटा टर्मिनल रेडी (डीटीआर) सिग्नल टॉगल किया जाता है, तो Arduino जैसे डिवाइस, प्रोग्रामिंग मोड में चले जाएंगे.

port.setSignals() और port.getSignals() को कॉल करने के बाद, क्रम से आउटपुट सिग्नल सेट करने और इनपुट सिग्नल पाने की प्रोसेस पूरी होती है. इस्तेमाल करने के उदाहरण यहां देखें.

// Turn off Serial Break signal.
await port.setSignals({ break: false });

// Turn on Data Terminal Ready (DTR) signal.
await port.setSignals({ dataTerminalReady: true });

// Turn off Request To Send (RTS) signal.
await port.setSignals({ requestToSend: false });
const signals = await port.getSignals();
console.log(`Clear To Send:       ${signals.clearToSend}`);
console.log(`Data Carrier Detect: ${signals.dataCarrierDetect}`);
console.log(`Data Set Ready:      ${signals.dataSetReady}`);
console.log(`Ring Indicator:      ${signals.ringIndicator}`);

स्ट्रीम का फ़ॉर्मैट बदला जा रहा है

जब आपको सीरियल डिवाइस से डेटा मिलता है, तो यह ज़रूरी नहीं है कि आपको सारा डेटा एक बार में मिले. इसे स्वेच्छा से अलग-अलग किया जा सकता है. ज़्यादा जानकारी के लिए, Streams API के सिद्धांत देखें.

इससे निपटने के लिए, TextDecoderStream जैसी पहले से मौजूद ट्रांसफ़ॉर्म स्ट्रीम का इस्तेमाल किया जा सकता है. इसके अलावा, खुद की ट्रांसफ़ॉर्म स्ट्रीम भी बनाई जा सकती है, जिससे आने वाली स्ट्रीम को पार्स करने के साथ-साथ पार्स किया गया डेटा वापस लाया जा सकता है. ट्रांसफ़ॉर्म स्ट्रीम, सीरियल डिवाइस और स्ट्रीम को इस्तेमाल करने वाले रीड लूप के बीच में होती है. यह डेटा खत्म होने से पहले, आर्बिट्रेरी ट्रांसफ़ॉर्मेशन ऐक्शन लागू कर सकता है. इसे किसी असेंबली लाइन की तरह देखें: विजेट लाइन में नीचे आने पर, लाइन का हर चरण विजेट में बदलाव करता है. इसलिए, जब वह आखिरी डेस्टिनेशन पर पहुंचता है, तो यह पूरी तरह से काम करने वाला विजेट बन जाता है.

हवाई जहाज़ फ़ैक्ट्री की फ़ोटो
दूसरे विश्व युद्ध का किला ब्रॉमविच एयरोप्लेन फ़ैक्ट्री

उदाहरण के लिए, ऐसी ट्रांसफ़ॉर्म स्ट्रीम क्लास बनाने का तरीका सोचें जो स्ट्रीम का इस्तेमाल करती हो और उसे लाइन ब्रेक के हिसाब से अलग-अलग करती हो. जब भी स्ट्रीम को नया डेटा मिलता है, तो इसके transform() तरीके को कॉल किया जाता है. वह या तो डेटा को इनक्यू में जोड़ सकता है या उसे बाद के लिए सेव कर सकता है. flush() वाले तरीके को तब कॉल किया जाता है, जब स्ट्रीम बंद होती है. यह ऐसे किसी भी डेटा को हैंडल करती है जो अभी तक प्रोसेस नहीं हुआ है.

ट्रांसफ़ॉर्म स्ट्रीम क्लास का इस्तेमाल करने के लिए, आपको किसी इनकमिंग स्ट्रीम को पाइप करना होगा. सीरियल पोर्ट से पढ़ें में दिए गए तीसरे कोड के उदाहरण में, ओरिजनल इनपुट स्ट्रीम को सिर्फ़ TextDecoderStream से ही पाइप किया गया था. इसलिए, हमें अपने नए LineBreakTransformer से उसे पाइप करने के लिए pipeThrough() को कॉल करना होगा.

class LineBreakTransformer {
  constructor() {
    // A container for holding stream data until a new line.
    this.chunks = "";
  }

  transform(chunk, controller) {
    // Append new chunks to existing chunks.
    this.chunks += chunk;
    // For each line breaks in chunks, send the parsed lines out.
    const lines = this.chunks.split("\r\n");
    this.chunks = lines.pop();
    lines.forEach((line) => controller.enqueue(line));
  }

  flush(controller) {
    // When the stream is closed, flush any remaining chunks out.
    controller.enqueue(this.chunks);
  }
}
const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable
  .pipeThrough(new TransformStream(new LineBreakTransformer()))
  .getReader();

सीरियल डिवाइस पर कम्यूनिकेशन से जुड़ी समस्याओं को डीबग करने के लिए, port.readable में मौजूद tee() तरीके का इस्तेमाल करें. इससे सीरियल डिवाइस पर की जाने वाली या उससे स्ट्रीम को अलग-अलग हिस्सों में बांटा जा सकता है. बनाई गई दोनों स्ट्रीम को अलग-अलग इस्तेमाल किया जा सकता है. इससे कंसोल पर किसी एक स्ट्रीम की जांच करने के लिए उसे प्रिंट किया जा सकता है.

const [appReadable, devReadable] = port.readable.tee();

// You may want to update UI with incoming data from appReadable
// and log incoming data in JS console for inspection from devReadable.

सीरियल पोर्ट का ऐक्सेस वापस लेना

वेबसाइट ऐसे सीरियल पोर्ट को ऐक्सेस करने के लिए अनुमतियां दे सकती है जिन्हें अब बनाए रखने में आपकी दिलचस्पी नहीं है. इसके लिए, SerialPort इंस्टेंस पर forget() को कॉल करें. जैसे, किसी शेयर किए गए कंप्यूटर पर कई डिवाइसों पर इस्तेमाल किए जाने वाले शिक्षा से जुड़े वेब ऐप्लिकेशन में, उपयोगकर्ता की जनरेट की गई बड़ी संख्या में अनुमतियों की वजह से, उपयोगकर्ता का अनुभव खराब होता है.

// Voluntarily revoke access to this serial port.
await port.forget();

Chrome 103 या उसके बाद के वर्शन में forget() उपलब्ध है. इसलिए, देखें कि यह सुविधा इनके साथ काम करती है या नहीं:

if ("serial" in navigator && "forget" in SerialPort.prototype) {
  // forget() is supported.
}

डेवलपर के लिए सलाह

Chrome में Web Serial API को डीबग करने के लिए, अंदरूनी पेज about://device-log पर जाएं. यहां आप सीरियल डिवाइस से जुड़े सभी इवेंट एक ही जगह पर देख सकते हैं.

Web Serial API को डीबग करने के लिए, अंदरूनी पेज का स्क्रीनशॉट.
Web Serial API को डीबग करने के लिए, Chrome में मौजूद इंटरनल पेज.

कोडलैब (कोड बनाना सीखना)

Google डेवलपर कोडलैब में, बीबीसी माइक्रो:बिट बोर्ड के साथ इंटरैक्ट करने के लिए वेब सीरियल एपीआई का इस्तेमाल करें, ताकि उसके 5x5 एलईडी मैट्रिक्स पर इमेज दिखाई जा सकें.

ब्राउज़र समर्थन

Web Serial API, Chrome 89 में सभी डेस्कटॉप प्लैटफ़ॉर्म (ChromeOS, Linux, macOS, और Windows) पर उपलब्ध है.

पॉलीफ़िल

Android पर WebUSB API और सीरियल एपीआई पॉलीफ़िल का इस्तेमाल करके, यूएसबी आधारित सीरियल पोर्ट काम कर सकते हैं. यह पॉलीफ़िल ऐसे हार्डवेयर और प्लैटफ़ॉर्म तक सीमित है जहां डिवाइस को WebUSB API की मदद से ऐक्सेस किया जा सकता है, क्योंकि डिवाइस में पहले से मौजूद किसी ड्राइवर ने इसका दावा नहीं किया है.

सुरक्षा और निजता

खास जानकारी वाले लेखकों ने वेब प्लैटफ़ॉर्म की बेहतर सुविधाओं का ऐक्सेस कंट्रोल करना में बताए गए मुख्य सिद्धांतों का इस्तेमाल करके, Web Serial API को डिज़ाइन और लागू किया है. इनमें उपयोगकर्ता कंट्रोल, पारदर्शिता, और एर्गोनॉमिक्स शामिल हैं. इस एपीआई का इस्तेमाल करने की सुविधा मुख्य रूप से, अनुमति वाले मॉडल से तय होती है. यह मॉडल एक बार में सिर्फ़ एक सीरियल डिवाइस को ऐक्सेस देता है. उपयोगकर्ता के किसी सवाल के जवाब में, उपयोगकर्ता को किसी सीरियल डिवाइस को चुनने के लिए, ऐक्टिव कार्रवाइयां करनी होंगी.

सुरक्षा से जुड़ी समस्याओं को समझने के लिए, Web Serial API के बारे में जानकारी देने वाले टूल के सुरक्षा और निजता सेक्शन देखें.

सुझाव/राय दें या शिकायत करें

Chrome टीम को Web Serial API के बारे में आपके विचार और अनुभव जानने में खुशी होगी.

हमें इस एपीआई के डिज़ाइन के बारे में बताएं

क्या एपीआई में ऐसा कुछ है जो उम्मीद के मुताबिक काम नहीं करता? इसके अलावा, क्या अपना आइडिया लागू करने के लिए, तरीके या प्रॉपर्टी मौजूद नहीं हैं?

Web Serial API GitHub के रेपो में किसी खास समस्या को दर्ज करें या अपने विचारों को किसी मौजूदा समस्या में जोड़ें.

लागू करने से जुड़ी समस्या की शिकायत करें

क्या आपको Chrome को लागू करने में कोई गड़बड़ी मिली? या क्या इसे लागू करने का तरीका खास जानकारी से अलग है?

https://new.crbug.com पर जाकर गड़बड़ी की शिकायत करें. ज़्यादा से ज़्यादा जानकारी दें, गड़बड़ी ठीक करने के लिए आसान निर्देश दें, और Blink>Serial पर कॉम्पोनेंट सेट करें. Glitch का इस्तेमाल करके, तुरंत और आसान तरीके शेयर करने में मदद मिलती है.

सहायता करें

क्या आपको Web Serial API इस्तेमाल करना है? आपकी सार्वजनिक मदद से, Chrome की टीम को सुविधाओं को प्राथमिकता देने में मदद मिलती है. साथ ही, इससे दूसरे ब्राउज़र वेंडर को पता चलता है कि उनकी मदद करना कितना ज़रूरी है.

हैशटैग #SerialAPI इस्तेमाल करके @ChromiumDev को एक ट्वीट भेजें और हमें बताएं कि उसका इस्तेमाल कहां और कैसे किया जा रहा है.

मददगार लिंक

डेमो

स्वीकार हैं

इस लेख पर मिली समीक्षाओं के लिए, रायली ग्रांट और जो मेडली का धन्यवाद. Unsplash पर बर्मिंघम म्यूज़ियम्स ट्रस्ट ने हवाई जहाज़ फ़ैक्ट्री की फ़ोटो ली है.