iPhone - как данные передаются в P2P

Я пытаюсь реализовать приложение P2P. Я пытаюсь передать данные настраиваемого класса NSObject между устройствами. Я не могу понять, когда GKSession вызывает метод «receiveData».

Вот что я сделал

  1. Обычное соединение и отображение диалогового окна со сверстниками

  2. Когда приложение получает изменение состояния для однорангового узла и состояние Connected, я отправляю данные всем одноранговым узлам (в идеале это должно вызываться, когда каждый одноранговый узел принимает соединение) с использованием методов NSCoding.

  3. В ReceiveData я декодирую NSData и возвращаю экземпляр NSObject.

Проблема в том, что метод session: peer: didChangeState: не вызывается на обоих устройствах. Он просто вызывается на устройстве, которое нажало кнопку «Подключить» в предупреждении PeerPicker.

Вопросы

  1. Когда вызывается didChangeState и для кого? Разве он не должен вызываться для каждого однорангового узла, когда они подключены?

  2. Когда вызывается метод receiveData: и для кого? Вызывается ли он для подтверждения получения сообщения (рукопожатия) или просто для передачи данных, отправленных другими узлами?

Спасибо за любую помощь.


person lostInTransit    schedule 05.07.2009    source источник


Ответы (1)


Думайте об этом больше как о «ведущем / ведомом», а не о «одноранговом узле». Предположительно обе стороны были настроены с помощью GameKit и назначили своих делегатов. Одна сторона, которая инициирует соединение, получает уведомление через значение изменения состояния GKPeerStateConnected о том, что получатель принял приглашение и соединение было установлено, поэтому он может начать пересылку материала.

Однако получающая сторона получает первое уведомление о том, что кто-то хочет поговорить с ней через didReceiveConnectionRequestFromPeer метод делегата. Он сохраняет сеанс для дальнейшего использования, затем разворачивается и вызывает acceptConnectionFromPeer, чтобы принять его. С этого момента он получает все, что было отправлено через метод receiveData.

Наилучший способ сделать это - иметь небольшой конечный автомат, который управляет состоянием каждой стороны. Отправитель отправляет сообщение только тогда, когда он получает событие GKPeerStateConnected. Получатель переводится в состояние connected, как только он принимает запрос на соединение, поэтому он может выполнить любую настройку, которую ему нужно сделать, прежде чем он начнет получать данные.

Поскольку сетевая абстракция GKSession, получатель может затем развернуться и использовать тот же экземпляр сеанса, который он получил в didReceiveConnectionRequestFromPeer, и использовать его для обратной записи отправителю (у которого должен быть свой собственный receiveData метод, вызываемый с ответами от получателя).

Следует иметь в виду, что существует неявное ограничение на размер данных в буфере, который вы можете отправить через GameKit. Возможно, вы захотите поэкспериментировать, чтобы найти, что это для вашей системы (я получаю что-то между 5K и 10K - по какой-то причине это варьируется). Вы можете захотеть иметь код для разделения ваших NSData на части и управления пакетированием / депакетированием данных.

person Ramin    schedule 05.07.2009
comment
Надеюсь, вы уже работаете в Apple. Это объяснение должно быть в официальной документации. - person typeoneerror; 02.06.2010