Как улучшить производительность CBCentralManager, когда CBPeripheralManager активен

Мы создали приложение для iOS, которое реализует CBCentralManager для подключения к созданному нами устройству, которое передает данные с частотой 10 Гц. Чрезвычайно важно, чтобы эти данные поступали и отображались быстро, поэтому мы создали строгие проверки задержек, если слишком много точек пропущено или если местные часы обнаружат, что входящие значения замедлены, мы сломаем и разорвем соединение.

Клиент попросил нас реализовать второе приложение для iOS, которое будет наблюдать первое. Мы внедрили CBPeripheralManager в исходное приложение, которое рекламирует, может подключаться и будет периодически публиковать свои данные для нескольких исходящих характеристик.

Мы обнаруживаем, что мы не можем подключить приложение iOS-наблюдатель к исходному приложению iOS (т. Е. Исходное приложение iOS имеет как CBCentral-соединение с устройством, так и CBPeripheral-соединение с приложением-наблюдателем, активным одновременно), без отключение проверки латентности входящих данных с устройства.

Я перепробовал все, что мог придумать, я использовал отдельные очереди для CBPeripheralManager и CBCentralManager, следующим образом:

    q = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
    ptr_CBPeriphMgr = [[CBPeripheralManager alloc] initWithDelegate:self queue:q];

Также,

  • Я зарегистрировал и отметил все, проверил, что ни один из моих кодов не занимает слишком много времени
  • Я переместил почти весь мой код из обработчиков BLE, чтобы сделать их очень легкими и не блокирующими,
  • Я пробовал отдельные очереди (пример, показанный выше), с низкими приоритетами
  • Я попытался замедлить скорость передачи данных CBPeripheralManager до минимума, несколько обновлений в секунду
  • Я пытался приостановить проверку задержек на три секунды после того, как установлено соединение CBPeripheralManager (что не очень идеально), но проблема возникает случайно, а не только после подключения.

Кажется, что независимо от того, что я пытаюсь, после того, как через 4-5 минут будут активны как периферийные, так и центральные соединения (у нас есть цикл, в котором второе приложение постоянно подключается и отключается каждые пять секунд, чтобы проверить соединение с устройством), мои входящие значения обновляются из устройство к центру замедляется примерно до 1/4 или 1/5 скорости, или они останавливаются на целую секунду, а затем три или четыре обновления приходят почти одновременно - оба из них отключают наши проверки задержки. Как будто какая-то очередь заполняется и производительность падает, но, как я упоминал выше, я думаю, что использую отдельные очереди.

Я в своем уме... есть ли у кого-нибудь мысли о том, как расставить приоритеты для моих центральных функций над моими периферийными функциями в приложении для iOS, или как-то улучшить производительность, чтобы не допустить проблем с этим и обеспечить реагирование моего приложения на 10 Гц? обновления с устройства, даже если наблюдаются как периферийные устройства?

(Отредактировано, чтобы указать, что мы повторно подключаем / отключаем второе приложение... возможно, я не очищаюсь после отключения должным образом, и мусор накапливается и портит BLE? Это объясняет, почему проблема возникает после 4 -5 минут независимо от частоты обновления данных по второму соединению.)

1 ответ

Решение

Вот некоторые предложения:

  • Попробуйте создать очереди, используя QOS_CLASS_USER_INITIATED или выше вместо QOS_CLASS_UTILITY,
  • Убедитесь, что вы звоните -[CBCentralManager stopScan] когда вам не нужно сканировать периферийные устройства, и -[CBPeripheralManager stopAdvertising] когда вам не нужно быть готовым к входящим соединениям (вероятно, когда вы подключены).
  • Вызов -[CBPeripheralManager setDesiredConnectionLatency:forCentral:] резервировать больше ресурсов.

Однако, если вы можете использовать iOS 11+, я бы порекомендовал уменьшить задержку и увеличить скорость, используя канал L2CAP. Хотя поддержка L2CAP в CoreBluetooth плохо документирована, вот список доступных API.

Другие вопросы по тегам