Проблема: я делаю офлайн-многопользовательскую игру для Android, в которой люди могут создавать или присоединяться к комнате и играть вместе через Wi-Fi. Рассмотрим ситуацию, когда пользователь создает комнату и он (конечно) должен сообщить всем остальным пользователям, что комната свободна. Итак, вопрос: «Как?». Я прочитал около 1000 раз это и это. Там написано, что для отправки каких-то данных на другое устройство одно из них должно быть сервером, а другое клиентом. Клиент отправляет некоторую информацию на сервер, сервер ее принимает. Значит ли это, что я должен сделать всех "игроков" серверами, а "создатель комнаты" должен стать клиентом? Это звучит безумно. Пожалуйста, помогите, может быть, я читаю не те документы?
Wi-Fi P2P. Информировать всех доступных пиров о некотором событии
Ответы (2)
Прежде всего, вам нужно помнить, что если вы решите использовать WiFiP2P
в своем проекте, вам нужно будет подготовиться к трудным временам. К сожалению (как вы уже могли заметить :)) WiFiP2P
официальная документация по Android не так хороша. Различные устройства ведут себя по-разному (например, они вызывают некоторые события WifiP2P
в разном порядке), и документы вообще не охватывают это. Достижение стабильной связи требует введения нестандартных, а иногда и кардинальных мер. Получение WifiP2P
соединения неразрывно связано с отображением системного окна (с вопросом, действительно ли вы хотите подключиться к устройству).
Перед тем, как приступить к реализации решения WifiP2P
, необходимо рассмотреть несколько моментов:
- Смогут ли игроки вашей игры подключаться более чем к одной комнате одновременно?
- Смогут ли игроки вашей игры обнаружить новую комнату, когда они подключены к другой?
- Смогут ли игроки вашей игры называть свои комнаты «человекочитаемыми» именами? И эти имена будут использоваться другими пользователями (не создателем комнаты) для выбора комнаты, к которой они хотели бы подключиться?
Сценарий А:
Если вы ответили «Да» на вопрос 1 или 2, вам нужно серьезно подумать, действительно ли вы хотите использовать WifiP2P
. WifiP2P
(реализация Wifi-Direct
для Android) не совсем соответствует вашим потребностям. Использование WifiP2P
, вероятно, означает, что владелец комнаты создает WifiP2P-group
, и любой человек, который хочет присоединиться к комнате, должен подключиться к этой WifiP2p-group
. Проблема в том, что Android не позволяет одному устройству присоединяться к нескольким группам одновременно (что также означает, что он не позволяет создавать несколько групп одновременно). Обнаружение изменений в доступных WiFiP2P
устройствах вокруг также проблематично (когда вы уже подключены к устройству).
Если вы действительно хотите использовать Wifi-Direct
, вам, вероятно, потребуется использовать один WiFiP2P-group
и подключить к нему все устройства. Эта группа будет действовать как обычная сеть, и всем, что связано с игровой комнатой, должен управлять один узел, выступающий в роли типичного сервера (или, может быть, не типичного сервера, а какого-то другого сетевого решения).
Если вам действительно не нужен WifiP2P
, используйте обычный Wifi
. Подключите все устройства к одной сети (возможно, даже создайте точку доступа на одном из ваших устройств), и весь процесс подключения может быть относительно простым, выполняемым в фоновом режиме без непосредственного участия пользователя. Удобочитаемые имена комнат не проблема, так как вы можете отправить что угодно со своего сервера.
Сценарий Б:
Если вы ответили «Да» на вопрос 3. и вам действительно нужно использовать WifiP2P
, вам нужно будет найти способ транслировать ваши «удобочитаемые» имена на другие устройства.
Вы, наверное, думаете, что это очень просто: вы подключаетесь к другому устройству, говорите название созданной вами комнаты, и все готово. Не так просто. Как я сказал ранее:
получение
WifiP2P
соединения неразрывно связано с отображением системного окна (с вопросом, действительно ли вы хотите подключиться к устройству)
Таким образом, весь процесс будет более-менее:
Устройство A: инициируйте подключение к устройству B (этот шаг также может быть выполнен устройством B)
Устройство B: появляется уродливое системное окно с вопросом, хотите ли вы подключиться к
Android-ao12ij219sa
(какое-то ПРОГРАММНО НЕИЗМЕНИМОЕ имя системного устройства)Устройство Б: принимает
Устройство B: ожидание результата подключения
Устройство B: подключено, ожидание информации о названии комнаты устройства A
Устройство А: подключено, отправляет название комнаты
Устройство B: получено имя комнаты устройства A, отключение (будущий запрос на подключение также приведет к отображению системного окна)
Пока выполняются шаги 1-7, никакое другое устройство не может подключиться к устройству А (поэтому в это время никакое другое устройство не может получить имя комнаты).
Что можно сделать:
Используйте
WifiP2P Service Discovery
. Это позволяет передавать некоторую информацию без необходимости установления соединения. К сожалению, он задокументирован еще хуже, чем самWifiP2P
, и может быть еще менее надежным (субъективно). Если вы хотите создать надежное решение, основанное на этом, вам придется потратить часы на тестирование и поиск различных случаев, в которых оно может не работать. Я знаю по опыту, что это возможно, но потребует от вас реализации ряда обходных путей, чтобы всегда можно было получить стабильноеWiFiP2P
соединение.Отправьте на свои устройства сопоставление между этими (неизменяемыми)
WifiP2P
именами и именами созданных комнат другим способом. Например, через API вашего сервера или что-то в этом роде...
@hide
через отражение. Я пытался использовать его для изменения имени устройства, и он отлично работает. Но все же процесс обнаружения идет с некоторыми странными проблемами. Например, устройство A продолжает получать намерение WIFI_P2P_PEERS_CHANGED_ACTION, которое содержит устройство B в списке узлов, даже если Wi-Fi на устройстве B отключен.
- person Niakros; 21.03.2016
@hide
deletePersistentGroup для удаления групп после отключения. Разве я не должен это делать?
- person Niakros; 21.03.2016
WifiP2p
(большинство моих сообщений о WifiP2P
относятся к первой половине прошлого года), и, честно говоря, я просто не могу вспомнить все, с чем столкнулся. Это. Вы пытались сбросить Wi-Fi, прежде чем вообще возиться с WifiP2p?
- person Bartek Lipinski; 30.03.2016
По сути, ваш дизайн, как я вижу, имеет очень простое решение для дизайна с Wifi Direct.
По сути, при создании «комнаты», к которой могут присоединиться другие, просто создайте группу, а затем добавьте локальную службу для рекламы комнаты.
обратите внимание, что вам может потребоваться начать обнаружение пиров, чтобы быть видимым с вашей локальной службой, по крайней мере, мой опыт показывает, что вам нужно как-то быть активным, иначе вы не сможете обнаружить.
Затем с клиентами просто выполните обнаружение службы, и как только вы найдете «комнату», просто подключитесь к ней.
Затем, когда соединения инициируются клиентами, диалоговые окна принятия должны отображаться на стороне владельцев группы.