Механизм межсетевого взаимодействия: стабильность и рекомендации

Я работаю над проектом, который использует MC framework как канал связи, и после некоторых тестов у меня есть мнение, что этот канал как-то нестабилен, чтобы полагаться.

Я слежу за документацией и видео Apple, чтобы правильно использовать фреймворк, но бывает, что:

  • peers get disconnected kinda 'часто после пары, и даже больше, если я соединяю более одного однорангового узла.
  • некоторые пакеты данных имеют смешанные данные

Есть ли какая-либо рекомендация по работе с каркасом? i.e:

  • Конкретные настройки проекта? (то есть: есть что-то в разделе возможностей, которое необходимо включить?)
  • Ограничения многопоточности? (т.е. всегда вызывать методы mc из того же потока)
  • Ограничения по количеству отправляемых данных

Я нашел эту ссылку, в которой упоминается что-то о том, что структура не работает нормально при стрессе. Это тот совет, который я ищу:).

Для записи:

  • Я использую реализацию на основе this после Проект Apple не работает для меня.
  • Я использую только один MCSession для всех сверстников, с которыми я пытаюсь соединиться с
  • Предпочтение шифрования установлено на MCEncryptionNone
  • Использование sendData: и sendResourceAtURL: для связи со сверстниками.

Ответы

Ответ 1

Я использую среду MC в игре и нашел несколько обходных путей для ее кажущейся нестабильности:

1) Я использую транзакцию "keep alive", отправляемую каждые 15 секунд, чтобы поддерживать активность по ссылкам. Я обнаружил, что это устраняет почти все потери связи, которые я испытывал.

2) Я отправляю всю обработку, инициированную приемом данных, в основной поток и никогда не переношу никакие объекты MCPeer или MCSession между потоками (кроме протокола начального подключения). Я также сделал это, чтобы свести к минимуму время, затрачиваемое на код приема данных, чтобы поток, используемый MC, как можно быстрее контролировал управление (что также явилось источником некоторых отключений). Я не применяю это правило для отправки данных (только при получении)

3) Я НЕ нашел чистого решения для повторения сверстников, которое появляется при попытке установить соединение (как с использованием стандартного пользовательского интерфейса, так и моего собственного). До сих пор сравнение идентификаторов MCPeer для избежания дубликатов только, кажется, устраняет часть дублирования. Кроме того, казалось, что использование той же MCSession для рекламы (MCAdvertiserAssistant) и подключение к одноранговым узлам вызвало некоторые конфликты, поэтому я использую новый отдельный экземпляр MCSession каждый раз, когда я запускаю помощника.

Ответ 2

Я использую его в приложении, которое регулярно передает большое количество данных. Несколько способов помогли:

  • Как только будет установлено соединение с одноранговым узлом, настройте пару NSOutputStream/NSInputStream для связи. Не используйте данные отправки или отправляйте методы ресурсов в инфраструктуре подключения многопользователей.

  • Если произойдет непредвиденное отключение, состояние объекта MCSession нельзя доверять - снести его и начать с нуля. ОБНОВЛЕНИЕ: неожиданное отключение здесь - это либо поток, который закрывается другим концом соединения.

  • Попросите своего пользователя проверить, что все устройства находятся в одной точке доступа WiFi. Если одноранговые узлы находятся в одном сетевом сегменте, но другой Wifi, браузеры будут видеть рекламодателей и смогут подключаться, но отключится через несколько секунд.

Update:

Чтобы установить выходной поток:

-(void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
{
    switch(state)
    {
        // ...

        case MCSessionStateConnected:
            outputStream = [session startStreamWithName:@"Stream" toPeer:peerID error:&error];
            // Setup a stream handler for the stream and open it
            break;
        // ...
    }
}

Чтобы установить входной поток, реализовать этот метод MCSessionDelegate:

-(void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID
{
    // Setup a stream handler for the stream and open it
}

Это будет вызвано, так как другой конец соединения откроет выходной поток.

Теперь у вас есть два потока, готовые к использованию для двунаправленной связи.