Web Bluetooth API לשילוב התקני BLE באתר שלך

מכשירי ה-BLE שלכם—מוני דופק, מנורות חכמות או חיישנים—דורשים אפליקציה ניידת שלא נוחה ויקרה לתחזוקה. אנחנו מחברים אותם לאתר שלכם באמצעות Web Bluetooth API, כך שמשתמשים יכולים לשלוט בהם ישירות מהדפדפן ללא התקנת תוכנה. הצוות שלנו מספק את הפרויקט במפתח מלא—מבדיקת פרוטוקול ועד יישום ותמיכה שוטפת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
Web Bluetooth API לשילוב התקני BLE באתר שלך
מורכב
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1502
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1307
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1050
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

תרחיש טיפוסי: יש לכם מכשיר BLE—מד דופק, מנורה חכמה או חיישן תעשייתי. היצרן מספק רק אפליקציה ניידת. אתם רוצים שמשתמשים יוכלו לשלוט במכשיר ישירות מהאתר שלכם ללא התקנת תוכנה. Web Bluetooth API פותר זאת, אך דורש טיפול קפדני בפרוטוקול, לוגיקת התחברות מחדש וניהול שגיאות. במשך 5 שנים השלמנו יותר מ-20 אינטגרציות BLE, מצמידי כושר ועד מוניטורים רפואיים. באמצעות הדפדפן תוכלו לחסוך עד 70% בפיתוח אפליקציות ניידות ולהפחית את זמן היציאה לשוק פי שלושה. עלות אינטגרציה טיפוסית היא $500–$2,000, וחוסכת אלפים בהשוואה לפיתוח מקורי. רוצים לחבר מכשיר BLE לאתר שלכם? נוכל להעריך את הפרויקט שלכם ביום אחד—פשוט צרו קשר.

אילו מכשירי BLE ניתן לחבר לאתר?

אנחנו מתחברים למדדי דופק, מדחומים, מנורות, בקרים—כל מכשיר עם Bluetooth Low Energy. המשתמש פותח דף, לוחץ על "התחבר", בוחר מכשיר מהרשימה, והאתר מתחיל לקרוא נתוני חיישנים, לשנות בהירות או להפעיל מנוע. המפתח הוא הבנת שירותי GATT ומאפיינים. אם קיימת תיעוד, האינטגרציה אורכת ימים. אם לא, אנחנו מבצעים הנדסה לאחור של הפרוטוקול באמצעות חיישן רשת.

מדוע Web Bluetooth API היא חלופה לאפליקציה ניידת

יישום מבוסס דפדפן מהיר פי שלושה מפיתוח מקורי ואינו דורש פרסום בחנות אפליקציות. המשתמש לא מוריד אפליקציה—הוא פשוט עוקב אחר קישור. עדכונים מוחלים מיידית בשרת, ללא ניהול גרסאות. עבור עסקים, זה מוריד את חסם הכניסה וחוסך עד 70% בתחזוקת שתי פלטפורמות.

כיצד להבטיח חיבור יציב לאחר ניתוק

זה קריטי למכשירים שדורשים זרם נתונים רציף. אנו מיישמים התחברות מחדש אוטומטית עם השהיה אקספוננציאלית: ניסיון ראשון לאחר שנייה אחת, שני לאחר 2, שלישי לאחר 4. לאחר שלושה כשלונות, אנו מציגים הודעה. להלן דוגמת קוד ב-TypeScript.

התחברות למכשיר

interface BluetoothDevice {
  name: string
  gatt: BluetoothRemoteGATTServer
}

async function connectToDevice(serviceUUID: string): Promise<BluetoothRemoteGATTServer> {
  const device = await navigator.bluetooth.requestDevice({
    filters: [{ services: [serviceUUID] }],
  })
  console.log(`Подключаемся к: ${device.name}`)
  device.addEventListener('gattserverdisconnected', () => {
    console.log('Устройство отключилось')
  })
  const server = await device.gatt!.connect()
  return server
}

קריאת נתונים: מד דופק

class HeartRateMonitor {
    private server: BluetoothRemoteGATTServer | null = null
    private characteristic: BluetoothRemoteGATTCharacteristic | null = null

    async connect() {
        this.server = await connectToDevice('heart_rate')
        const service = await this.server.getPrimaryService('heart_rate')
        this.characteristic = await service.getCharacteristic('heart_rate_measurement')
        await this.characteristic.startNotifications()
        this.characteristic.addEventListener(
            'characteristicvaluechanged',
            this.handleHeartRateMeasurement.bind(this)
        )
    }

    private handleHeartRateMeasurement(event: Event) {
        const value = (event.target as BluetoothRemoteGATTCharacteristic).value!
        const flags = value.getUint8(0)
        let heartRate: number
        if (flags & 0x01) {
            heartRate = value.getUint16(1, true)
        } else {
            heartRate = value.getUint8(1)
        }
        const rrIntervals: number[] = []
        if (flags & 0x10) {
            for (let i = 2; i + 1 < value.byteLength; i += 2) {
                rrIntervals.push(value.getUint16(i, true) / 1024 * 1000)
            }
        }
        console.log(`ЧСС: ${heartRate} уд/мин, RR: [${rrIntervals.join(', ')}] мс`)
    }

    async disconnect() {
        await this.characteristic?.stopNotifications()
        this.server?.disconnect()
    }
}

כתיבת נתונים: שליטה במנורה חכמה

class SmartLightController {
  private server: BluetoothRemoteGATTServer | null = null
  private controlChar: BluetoothRemoteGATTCharacteristic | null = null
  private readonly SERVICE_UUID = '00010203-0405-0607-0809-0a0b0c0d1910'
  private readonly CONTROL_UUID = '00010203-0405-0607-0809-0a0b0c0d2b11'

  async connect() {
    this.server = await connectToDevice(this.SERVICE_UUID)
    const service = await this.server.getPrimaryService(this.SERVICE_UUID)
    this.controlChar = await service.getCharacteristic(this.CONTROL_UUID)
  }

  async setColor(r: number, g: number, b: number) {
    const command = new Uint8Array([
      0x33, 0x05, 0x02, r, g, b, 0x00, 0x00, 0x00, r ^ g ^ b,
    ])
    await this.controlChar!.writeValueWithResponse(command)
  }

  async setBrightness(level: number) {
    const command = new Uint8Array([
      0x33, 0x04, Math.round(level * 2.55), 0x00,
    ])
    await this.controlChar!.writeValueWithoutResponse(command)
  }

  async readBatteryLevel(): Promise<number> {
    const service = await this.server!.getPrimaryService('battery_service')
    const char = await service.getCharacteristic('battery_level')
    const value = await char.readValue()
    return value.getUint8(0)
  }
}

React Hook לניהול חיבורים

function useBluetooth() {
  const [device, setDevice] = useState<BluetoothRemoteGATTServer | null>(null)
  const [isConnected, setIsConnected] = useState(false)
  const [isSupported] = useState(() => 'bluetooth' in navigator)
  const [error, setError] = useState<string | null>(null)

  const connect = useCallback(async (serviceUUID: string) => {
    try {
      setError(null)
      const server = await connectToDevice(serviceUUID)
      setDevice(server)
      setIsConnected(true)
    } catch (err) {
      if ((err as Error).name === 'NotFoundError') {
        setError('Устройство не выбрано')
      } else {
        setError((err as Error).message)
      }
    }
  }, [])

  const disconnect = useCallback(() => {
    device?.disconnect()
    setDevice(null)
    setIsConnected(false)
  }, [device])

  return { device, isConnected, isSupported, error, connect, disconnect }
}

התחברות מחדש לאחר ניתוק

device.addEventListener('gattserverdisconnected', async () => {
  let retries = 0
  while (retries < 3) {
    await new Promise((r) => setTimeout(r, 1000 * (retries + 1)))
    try {
      await device.gatt!.connect()
      await resubscribeCharacteristics()
      console.log('Переподключено')
      return
    } catch {
      retries++
    }
  }
  console.error('Не удалось переподключиться')
})

מקרה אמיתי: אינטגרציה בפלטפורמת כושר

בפרויקט אחד עבור סטארטאפ למעקב כושר, שילבנו מד דופק BLE ששידר נתונים כל שנייה. היישום המקורי היה בעל עיכוב של 4 שניות עקב גילוי שירות GATT לא יעיל. על ידי שמירת מזהי שירות במטמון ואופטימיזציה של הרשמות להתראות מאפיינים, צמצמנו את זמן החיבור הראשוני ל-0.5 שניות וביטלנו את עיכוב הנתונים. הפלטפורמה תומכת כעת בתצוגת דופק בזמן אמת עם התחברות מחדש אוטומטית, ומשרתת למעלה מ-10,000 משתמשים פעילים יומית.

השוואה: Web Bluetooth API לעומת אפליקציה מקורית

קריטריון Web Bluetooth API אפליקציה מקורית
זמן פיתוח 1–2 שבועות 2–3 חודשים
אספקה קישור חנויות אפליקציות
עדכונים מיידיים ידניים, דרך החנות
פלטפורמות Chrome/Edge iOS, Android
מורכבות בינונית גבוהה
עלות החל מ-$500 החל מ-$5,000

טעויות נפוצות באינטגרציית BLE

המכשיר לא מופיע במהלך הסריקה. ודאו שהאתר מוגש באמצעות HTTPS ובקשו הרשאת Bluetooth. לעיתים קרובות הסיבה היא חסר interface BluetoothDevice { name: string gatt: BluetoothRemoteGATTServer } async function connectToDevice(serviceUUID: string): Promise<BluetoothRemoteGATTServer> { const device = await navigator.bluetooth.requestDevice({ filters: [{ services: [serviceUUID] }], }) console.log(`Подключаемся к: ${device.name}`) device.addEventListener('gattserverdisconnected', () => { console.log('Устройство отключилось') }) const server = await device.gatt!.connect() return server } . החיבור נופל במעבר לרקע. השתמשו ב-class HeartRateMonitor { private server: BluetoothRemoteGATTServer | null = null private characteristic: BluetoothRemoteGATTCharacteristic | null = null async connect() { this.server = await connectToDevice('heart_rate') const service = await this.server.getPrimaryService('heart_rate') this.characteristic = await service.getCharacteristic('heart_rate_measurement') await this.characteristic.startNotifications() this.characteristic.addEventListener( 'characteristicvaluechanged', this.handleHeartRateMeasurement.bind(this) ) } private handleHeartRateMeasurement(event: Event) { const value = (event.target as BluetoothRemoteGATTCharacteristic).value! const flags = value.getUint8(0) let heartRate: number if (flags & 0x01) { heartRate = value.getUint16(1, true) } else { heartRate = value.getUint8(1) } const rrIntervals: number[] = [] if (flags & 0x10) { for (let i = 2; i + 1 < value.byteLength; i += 2) { rrIntervals.push(value.getUint16(i, true) / 1024 * 1000) } } console.log(`ЧСС: ${heartRate} уд/мин, RR: [${rrIntervals.join(', ')}] мс`) } async disconnect() { await this.characteristic?.stopNotifications() this.server?.disconnect() } } או יישמו התחברות מחדש אוטומטית. פענוח נתונים שגוי. בדקו דגלי סיביות וסדר בתים (little-endian).

אילו דפדפנים תומכים ב-Web Bluetooth?

כיום, ה-API עובד ב-Chrome 70+, Edge 79+ ו-Chrome Android. Firefox ו-Safari אינם תומכים בו. אם הקהל שלכם משתמש בדפדפנים אלה, נוכל להציע פתרונות חלופיים: Native Messaging, PWA עם Service Worker, או אפליקציה היברידית. עבור רוב התרחישים העסקיים, Chrome הוא הבחירה הסטנדרטית.

תוכנית עבודה ולוח זמנים

שלב משך
ניתוח מסמכים והנדסה לאחור 1–3 ימים
עיצוב ארכיטקטורה וממשק משתמש 1–2 ימים
יישום חיבורים וניהול שגיאות 2–4 ימים
בדיקה על מכשיר אמיתי 1–2 ימים
פריסה וניטור 0.5–1 יום

אינטגרציה עם מכשיר מתועד: 3–5 ימים. עבור מכשירים לא מתועדים (הנדסה לאחור של פרוטוקול): 7–12 ימים. העלות נעה בין $500 ל-$2,000 בהתאם למורכבות ולצרכי ממשק המשתמש. נוכל להעריך את הפרויקט שלכם בתוך יום עסקים אחד—פשוט צרו קשר. קבלו ייעוץ על אינטגרציית BLE עוד היום.

מה כלול

  • תיעוד מלא של הפרוטוקול וקוד האינטגרציה.
  • גישה למאגר עם קוד מקור והוראות פריסה.
  • הדרכה לצוות שלכם על תחזוקה והרחבת האינטגרציה.
  • תמיכה ל-30 יום לאחר ההשקה (תיקוני באגים, ייעוץ).
  • זמינות מובטחת עם התחברות מחדש אוטומטית.
  • מהנדסים מוסמכים עם ניסיון של 5+ שנים ב-BLE.

עם ניסיון של 5+ שנים ב-BLE ו-20+ אינטגרציות מוצלחות, הצוות שלנו מספק פתרונות אמינים.

מדריך שלב אחר שלב

  1. בדקו תמיכת דפדפן: class SmartLightController { private server: BluetoothRemoteGATTServer | null = null private controlChar: BluetoothRemoteGATTCharacteristic | null = null private readonly SERVICE_UUID = '00010203-0405-0607-0809-0a0b0c0d1910' private readonly CONTROL_UUID = '00010203-0405-0607-0809-0a0b0c0d2b11' async connect() { this.server = await connectToDevice(this.SERVICE_UUID) const service = await this.server.getPrimaryService(this.SERVICE_UUID) this.controlChar = await service.getCharacteristic(this.CONTROL_UUID) } async setColor(r: number, g: number, b: number) { const command = new Uint8Array([ 0x33, 0x05, 0x02, r, g, b, 0x00, 0x00, 0x00, r ^ g ^ b, ]) await this.controlChar!.writeValueWithResponse(command) } async setBrightness(level: number) { const command = new Uint8Array([ 0x33, 0x04, Math.round(level * 2.55), 0x00, ]) await this.controlChar!.writeValueWithoutResponse(command) } async readBatteryLevel(): Promise<number> { const service = await this.server!.getPrimaryService('battery_service') const char = await service.getCharacteristic('battery_level') const value = await char.readValue() return value.getUint8(0) } } .
  2. בקשו את המכשיר: function useBluetooth() { const [device, setDevice] = useState<BluetoothRemoteGATTServer | null>(null) const [isConnected, setIsConnected] = useState(false) const [isSupported] = useState(() => 'bluetooth' in navigator) const [error, setError] = useState<string | null>(null) const connect = useCallback(async (serviceUUID: string) => { try { setError(null) const server = await connectToDevice(serviceUUID) setDevice(server) setIsConnected(true) } catch (err) { if ((err as Error).name === 'NotFoundError') { setError('Устройство не выбрано') } else { setError((err as Error).message) } } }, []) const disconnect = useCallback(() => { device?.disconnect() setDevice(null) setIsConnected(false) }, [device]) return { device, isConnected, isSupported, error, connect, disconnect } } .
  3. התחברו לשרת GATT: device.addEventListener('gattserverdisconnected', async () => { let retries = 0 while (retries < 3) { await new Promise((r) => setTimeout(r, 1000 * (retries + 1))) try { await device.gatt!.connect() await resubscribeCharacteristics() console.log('Переподключено') return } catch { retries++ } } console.error('Не удалось переподключиться') }) .
  4. קבלו את השירות והמאפיין הרצויים.
  5. התחילו לקרוא או לכתוב נתונים.
  6. טפלו בניתוק: הירשמו לאירוע optionalServices.
מהם שירותי ומאפייני GATT? GATT (Generic Attribute Profile) הוא פרוטוקול המגדיר את מבנה הנתונים של מכשיר BLE. שירות הוא קבוצת מאפיינים (לדוגמה, שירות "סוללה"). מאפיין הוא פרמטר ספציפי (לדוגמה, רמת סוללה). לכל שירות ומאפיין יש UUID ייחודי.

מידע נוסף על הטכנולוגיה: תיעוד רשמי ו-מאמר בוויקיפדיה.