Wi-Fi P2P. Сообщите всем сверстникам о каком-либо событии

Проблема: я создаю автономную многопользовательскую игру для Android, где люди могут создавать или присоединяться к комнате и играть вместе через Wi-Fi. Рассмотрим ситуацию, когда пользователь создает комнату, и он (конечно) должен сообщить всем другим пользователям, что есть доступная комната. Итак, вопрос: «Как?». Я читал около 1000 раз это и это . Там написано, что для отправки некоторых данных на другое устройство один из них должен быть сервером, а другой – клиентом. Клиент отправляет информацию на сервер, сервер принимает его. Итак, значит ли это, что я должен заставить всех «игроков» серверов, и «создатель комнаты» должен стать клиентом? Это звучит безумно. Пожалуйста, помогите, может быть, я читаю неправильные документы?

Прежде всего вам нужно помнить, что если вы решите использовать WiFiP2P в своем проекте, вам нужно будет подготовиться к трудному времени. К сожалению (как вы уже заметили :)) Официальная документация WiFiP2P Android не так WiFiP2P . Различные устройства ведут себя по-разному (например, они вызывают некоторые события WifiP2P в разном порядке), и документы вообще не покрывают его. Достижение стабильной связи требует введения нетрадиционных и иногда радикальных мер. Получение соединения WifiP2P неразрывно связано с отображением системного окна (с вопросом, действительно ли вы хотите подключиться к устройству).

Перед началом внедрения решения WifiP2P вам нужно рассмотреть несколько вещей:

  1. Смогут ли игроки вашей игры одновременно подключаться к нескольким комнатам?
  2. Смогут ли игроки вашей игры обнаружить новую комнату при подключении к другой?
  3. Смогут ли игроки вашей игры назвать свои комнаты «человекочитаемыми» именами? И эти имена будут использоваться другими пользователями (а не создателем комнаты), чтобы выбрать комнату, к которой они хотели бы подключиться?

Сценарий A:

Если вы ответили «Да» на вопрос 1. или 2., вам серьезно нужно подумать, действительно ли вы хотите использовать WifiP2P . WifiP2P (реализация Android Wifi-Direct ) не соответствует вашим потребностям. Использование WifiP2P , вероятно, означает, что владелец комнаты создает группу WifiP2P-group и любой человек, желающий присоединиться к комнате, должен подключиться к этой WifiP2p-group . Проблема заключается в том, что Android не позволяет одному устройству одновременно подключаться к нескольким группам (что также означает, что он не позволяет одновременно создавать несколько групп). Обнаружение изменений в доступных устройствах WiFiP2P также проблематично (когда вы уже подключены к устройству).

Если вы действительно хотите использовать Wifi-Direct вам, вероятно, потребуется использовать одну WiFiP2P-group и подключить к ней все устройства. Эта группа будет действовать точно так же, как обычная сеть, и всем связанным с игрой игрокам придется управлять одним узлом, выступающим в качестве типичного сервера (или, возможно, не типичного сервера, а другого сетевого решения).

Если вам действительно не нужен WifiP2P используйте только обычный Wifi . Подключите все устройства к одной сети (возможно, даже запустите точку доступа на одном из ваших устройств), и весь процесс соединения может быть относительно простым, выполненным в фоновом режиме, без непосредственного участия в нем. Человеко-читаемые имена комнат не являются проблемой, поскольку вы можете отправлять что-либо с вашего сервера.

Сценарий B:

Если вы ответили «Да» на вопрос 3. и вам действительно нужно использовать WifiP2P , вам нужно будет найти способ транслировать ваши «удобочитаемые» имена на другие устройства.

Вы, наверное, думаете, что это очень просто: вы подключаетесь к другому устройству, говорите имя комнаты, которую вы создали, и все готово. Не так просто. Как я сказал ранее:

Получение соединения WifiP2P неразрывно связано с отображением системного окна (если вы действительно хотите подключиться к устройству)

Таким образом, весь процесс будет более-менее:

  1. Устройство A: инициирует подключение к устройству B ( этот шаг также может выполняться устройством B )

  2. Устройство B: появляется уродливое системное окно, спрашивающее вас, хотите ли вы подключиться к Android-ao12ij219sa (некоторое имя системного устройства PROGRAMMATICALLY UNCHANGEABLE )

  3. Устройство B: принятие

  4. Устройство B: ожидание результата подключения

  5. Устройство B: подключено, ожидая информации об имени комнаты устройства A

  6. Устройство A: подключено, имя отправителя

  7. Устройство B: полученное имя комнаты устройства A, отсоединение (в будущем запрос на подключение также приведет к отображению системного окна)

Хотя шаги 1-7 не выполняются, никакое другое устройство не может подключиться к устройству А (поэтому в течение этого времени никакое другое устройство не может получить имя комнаты).

Что можно сделать:

  1. Используйте WifiP2P Service Discovery . Он позволяет передавать некоторую информацию без необходимости подключения. К сожалению, он даже хуже документирован, чем сам WifiP2P , и он может быть даже менее надежным (субъективно). Если вы хотите сделать надежное решение, основанное на этом, вам нужно будет потратить часы на тестирование и найти разные случаи, когда он может не работать. Я знаю по опыту, что это возможно, но потребует от вас нескольких обходных решений, которые будут реализованы, чтобы он всегда мог получить стабильное соединение WiFiP2P .

  2. Отправьте на свои устройства, сопоставление между этими (неизменяемыми) именами WifiP2P именами комнат, другими словами. Например, через ваш сервер api или что-то еще …

В принципе, ваш дизайн, как я вижу, имеет очень простое решение для дизайна с Wifi Direct.

В основном при создании «комнаты», к которой может присоединиться другая, просто создайте группу, а затем добавьте локальную услугу, чтобы рекламировать комнату.

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

Затем с клиентами просто выполняйте поиск сервиса, и как только вы найдете «комнату», просто подключитесь к ней.

Затем, когда соединения инициируются клиентами, диалоги принятия должны отображаться на стороне владельцев групп.