- PVSM.RU - https://www.pvsm.ru -
Мотивом написания данного приложения послужила курсовая работа по дисциплине «Компьютерные системы и сети». Честно говоря, эта одна из самых мной нелюбимых сторон в компьютерных технологиях, и я решил «подстраивать» курсовой проект под свои интересы, а именно, под Андроид-разработку.
Было решено создать библиотеку для соединения Андроид-устройств по средством Wi-Fi Direct технологии и передачи данных между ними (Wi-Fi Peer-to-Peer соединение осуществляется как раз с помощью технологии Wi-Fi Direct).
После одобрения идеи о локальном соединении устройств передо мной встал вопрос: С помощью какой технологии собираюсь я это осуществить? Рассматривались следующие варианты:
Основными недостатками данного подхода являются ограничение пользователей в одной сети и малый радиус действия. Я же хочу создать группу устройств, общающихся между собой на расстоянии не менее 10 метров.
Создание точки доступа является не плохим вариантом, однако меня смущает ситуация с потерей основного Wi-Fi соединения. Я бы хотел, чтобы пользователи могли находится в локальной сети, и одновременно иметь доступ к глобальной, например быть подключенными к своему домашнему роутеру.
Однако с помощью Wi-Fi Hotspot можно добиться максимальной скорости передачи данных (приложения Portal [1], SHAREit [2]).
Данный подход решает все вышеупомянутые проблемы:
Но сразу закрадывается сомнение, мол Wi-Fi Peer-to-Peer, тогда как мы собираемся создать группу с владельцем и клентами, и тем более, чтобы все друг с другом общались. Это как раз-таки и является основной причиной написания данной статьи.
Этот вариант не упоминал в основном списке, т.к. не считаю, что он может полноценно подойти для выполнения поставленной задачи. Однако Wi-Fi Aware является сравнительно молодой технологией для рассылки сообщений в определенном радиусе действия.
Скажу честно, предоставляемая документация [3] by developer.android.com давалась мне нелегко. И я начал искать сэмплы. Перебрав кучу материала, наткнулся на наиболее интересный sample by Google [4].
Никогда не думал, что на официальном сайте от Google можно найти говнокод, но это как раз тот случай. Однако даже этому стоит отдать должное, так как благодаря данному ресурсу я реализовал то, что хотел.
В сэмпле продемонстрирован пример чата двух устройств, которые нашли друг друга в списке, отображающем рядом находящиеся Wi-Fi Direct устройства с запущенным приложением чата. При выборе партнера непосредственно открывается ChatActivity.
Очень важным моментом является поиск собеседников: в списке не будут отображаться такие Wi-Fi Direct устройства, как телевизор или какая-нибудь гарнитура. Отображаются только устройства с запущенным Chat-приложением.
Также присутствовала проблема с тестированием. Тестировать работоспособность приложения необходимо было исключительно на реальных устройствах.
Приложение представляет следующий функционал:
Описание экранов слева-направо:
После выбора пользователем, в какую группу присоединиться, владельцу группы приходит сообщение об установлении связи с данным устройством.
Логика построена на основе архитектуры клиент-сервер. Сервером является владелец группы, клиентами — подсоединившиеся пользователи.
В приложении присутствуют собственные Serializer/Deserializer для преобразования передаваемых данных в массив байтов и обратно. В передаваемых данных хранится следующая информация:
Первый пункт «кому отправить» не совсем корректен, т.к. отправляются данные всем. Сначала серверу, потом сервер отправляет этот пакет всем клиентам. А вот клиент уже сам решает, стоит ему обрабатывать эти данные или нет. Сделано это по той простой причине, что сервер не знает ролей его клиентов. Таким образом было достигнуто равноправие в группе. Владелец отличается от всех остальных только тем, что его обременили заниматься передачей данных всем его клиентам.
Когда проект дошел до стадии тестирования мультиплеера (> 2 устройств), тут-то и началась жара. Два устройства как и прежде у меня соединялись без проблем (для чего впрочем и создан Wi-Fi Peer-to-Peer), однако при подсоединении третьего звена почти всегда происходил треш. При нажатии на кнопку у «владельца» (позже поймете, почему в кавычках) цвет менялся только у того клиента, с которым «владелец» последний раз общался.
После долгих и упорных часов раздумий я решил соединить устройства через опцию Wi-Fi Direct в настройках Wi-Fi каждого, и заметил вещь, которая перевернула мое сознание и добавила всего одну строчку в код метода для установки соединения.
До этого я считал, что тот девайс, который подсоединяется к другому, всегда будет клиентом… а это далеко не так. При соединении устройств рандомно передавались права владельца одному из них, что и побудило меня на поиск настройки config'a, который бы исправил эту ситуацию, и сделал подсоединяемое устройство клиентом.
При соединении двух устройств прописывается специальный config, который в себе содержит:
final WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = deviceAddress;
config.wps.setup = WpsInfo.PBC;
config.groupOwnerIntent = status.getIntent();
mWifiP2pManager.connect(mWifiP2pManagerChannel, config, null);
Status'ом (enum) выше является текущее положение устройства, если он создатель группы — GroupOwner, иначе — Client.
Пока не существует решения по проблеме восстановления соединения. Например, при выходе из приложения, например, чтобы совершить звонок, после возвращения нас ждет… ничего. После дестроя активности необходимо опять подтягивать клиентов себе, а клиентам — владельца.
Также хочется ввести понятие по передаче прав владельца одному из клиентов на тот случай, если владельцу группы необходимо покинуть игру.
Защита. Для входа в определенную группу было бы неплохо реализовать авторизацию.
Не думаю, что я реализовал что-то новое или революционное, однако данный проект послужил хорошим примером неординарного использования Wi-Fi Peer-to-Peer соединения. Мною была успешно построена сеть между устройствами с помощью Wi-Fi Direct, что позволило беспрепятственно общаться между ними.
Это моя первая статья, поэтому судить строго. Спасибо за внимание.
→ Ссылка на GitHub [5]
(модуль wifidirect может быть без проблем перенесен в любой андроид-проект)
Автор: chelsenok
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android-development/260468
Ссылки в тексте:
[1] Portal: https://play.google.com/store/apps/details?id=com.pushbullet.android.portal&hl=en
[2] SHAREit: https://play.google.com/store/apps/details?id=com.lenovo.anyshare.gps&hl=en
[3] документация: https://developer.android.com/guide/topics/connectivity/wifip2p.html
[4] sample by Google: https://android.googlesource.com/platform/development/+/master/samples/WiFiDirectServiceDiscovery/
[5] Ссылка на GitHub: https://github.com/chelsenok/WiFi-Direct-Game
[6] Источник: https://habrahabr.ru/post/333388/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.