- Оригинальный адрес:Animated QR data transfer with Gomobile and Gopherjs
- Оригинальный автор:Divan
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:EmilyQiRabbit
- Корректор:suhanyujie
Динамическая передача данных QR-кода с использованием Gomobile и Gopherjs
Это слишком длинно и не хочется читать, поэтому сразу даю вывод полного текста: Это проект осуществляется в выходные дни и хочет передавать данные через динамические QR коды.Проект запрограммирован на языке Go и использует код стирания фонтана. Мобильное приложение использует Gomobile, который может повторно использовать код Go, а для веб-приложения, чтобы автоматически тестировать параметры QR-кода, проект построен с использованием фреймворков GopherJS и Vecty.
Я поделюсь своим опытом создания этого проекта, а также кодом и результатами тестов с использованием динамических QR-кодов в качестве средства передачи данных.
Сложные проблемы
Однажды я попытался найти возможное решение в следующем сценарии:
Допустим, вы находитесь в людном месте, и вдруг ваше приложение для обмена сообщениями перестает работать, потому что диктатура блокирует общение. Может, просто заблокировали IP-адреса узлов, отправляющих и принимающих сообщения, или ограничили доступ к некоторым хостам через государственного DNS-провайдера, или отключили другие VPN и прокси-сервисы — тут неважно, в какую сторону. Вопрос в том, если хотя бы одно устройство все еще может успешно подключиться к Интернету, как вы можете восстановить сетевое подключение других и иметь возможность делиться информацией о подключении с другими.
Если эту часть расширить, длина будет очень большой, но самая важная концепция, которую необходимо понять, это:порог просачивания. Проще говоря, если соединить узлы в решетке или графе (или людей в толпе) с вероятностью p, то при некоторой критической вероятностиp0 будут большие кластеры и дальние связи. Проще говоря, если все в толпе и вокруг нихnЛюди обмениваются информацией, тогда вы можете применить математическую точность, гарантирующую, что каждый получит эту информацию.
В случае, например, запуска узла IP это означает, что соединения со всеми приложениями будут восстановлены.
Хорошо, теперь вернемся к нашему вопросу — когда вы находитесь в враждебной среде и вам отрезана часть сети, как вы можете быстро передавать произвольные фрагменты информации из одного приложения в другое? Первая мысль — использовать Bluetooth, но для этого требуется долгий и утомительный процесс обнаружения устройств и определения имен устройств, и во многих случаях Bluetooth — это проблема «не удается подключиться по какой-либо причине». Кроме того, NFC — отличная идея — вы можете подключить один телефон напрямую к другому — но главный недостаток заключается в том, что все еще есть много телефонов и планшетов, которые не поддерживают NFC или имеют ограниченную поддержку. Итак, что насчет QR-кодов?
QR код
QR кодэто очень популярное визуальное кодирование, используемое в различных отраслях. Он поддерживает несколько различных уровней восстановления после ошибок с почти 30% избыточной информацией. Версия с максимальной емкостью (версия 40) позволяет кодировать до 4296 букв или 2953 двоичных символов.
Но есть две очевидные проблемы:
- Скорость передачи 3-4 КБ, вероятно, недостаточно
- Чем больше данных содержится в QR-коде, тем выше качество и разрешение изображения.
В этом случае я хочу иметь возможность передавать около 15 КБ данных между пользовательскими устройствами средней производительности, поэтому естественно подумать, почему бы не использовать динамический QR-код с динамическим FPS и изменяющимся размером?
Я быстро изучил некоторые работы, проделанные предшественниками, и обнаружил, что естьНемного сродни проект, в основном как хакерские проекты, или даже какТезиси использует Java, Python или JavaScript в качестве языка программирования. Это означает, что эти коды не могут быть кроссплатформенными и не могут быть по-настоящему повторно использованы, поэтому мой проект приходится реализовывать с нуля. К счастью, поскольку QR-коды очень популярны и используются многими людьми, недостатка в кодовых базах, связанных с этим, нет, а парсинг QR-кодов даже встроен в ПО камеры большинства производителей смартфонов. (Именно поэтому люди не разрабатывают другие способы добавления функциональности к QR-кодам, такие как цветные QR-коды, где в цветных QR-кодах используется дополнительный уровень цветового кодирования или даже что-то более крутое, например, кодирование яркости, которое яблоки используют для своих целей.Облако частиц во время сопряжения Apple Watchтуда).
TXQR
Так начался мой проект выходного дня. Слово TxQR означает передачу через QR-код (Tx).
Ниже приведены основные дизайнерские идеи этого проекта. Клиенту необходимо выбрать данные для отправки, сгенерировать динамические QR-коды и отображать их в цикле, пока все кадры не будут получены считывающим устройством. Кодировка устроена таким образом, что может поддерживать любой порядок кадров, а также динамическое изменение FPS или размера кодируемого блока. Это сделано для того, чтобы считывающее устройство работало очень медленно, а также могло отображать сообщение «Пожалуйста, уменьшите FPS отправляющего устройства», а затем продолжать получать тот же файл, даже размер кадра изменится.
Протокол TXQR очень прост — каждый кадр начинается с «NUM/TOTAL|», (NUM и TOTAL — целые числа, представляющие текущий отправленный и полученный кадр и общее количество кадров соответственно). Остальное — это содержимое файла. Для создания двоичного содержимого необработанные данные кодируются с использованием Base64, поэтому в QR-код фактически кодируются только буквы и цифры. Затем все кадры отображаются в бесконечном цикле с заданным FPS.
Это очень просто,здесьЕсть реализация этого протокола на языке Go, а для кодирования и декодирования QR-кодов сделан простой пакет. Самая крутая часть — сделать этот код доступным и для мобильных приложений.
Обновление: txqr теперь использует более эффективный метод, т.е.фонтан двор.последующие статьиЕсть подробные объяснения и сравнения результатов тестов, и вы можете просмотреть их, если вам интересно.
Gomobile
спасибо, что естьgomobile, проект становится очень простым.
файл со стандартным кодом Go, который вы только что написали, и запуститеgomobile bind ...
, через несколько секунд вы можете.framework
или.aar
Файл добавляется в ваш проект iOS или Android, вы можете ссылаться на него, как на любую другую обычную библиотеку, и автоматически получать завершение имени и ввод информации.
Я быстро создал простой сканер QR-кода iOS в Swift (спасибо Саймону Нг).Замечательное введение), а затем настроенный для чтения динамических QR-кодов, он передает декодеру txqr фрагменты данных, которые необходимо декодировать, а затем отображает полученный файл в окне предварительного просмотра.
Всякий раз, когда я застреваю с вопросом типа «как что-то сделать в Swift», обычно гораздо проще решить в Go, а потом просто вызывать методы в библиотеке напрямую, как описано выше. Но, пожалуйста, не поймите меня неправильно, Swift превосходен во многих аспектах и является очень хорошим языком программирования, но он предоставляет много решений для одной вещи, плюс есть много исторических версий, которые сильно изменились, что заставляет вас всегда долго искать в Google или stackoverflow что-то столь же простое, как «как рассчитать время с точностью до миллисекунды». Потратив 40 минут, я решил использовать Go и просто вызвать функциюtime.Since(start)
, затем преобразуйте код и используйте его непосредственно в Swift.
Я также написал инструмент командной строки, который отображает QR-коды на консоли для быстрого тестирования приложения. Собрав все это вместе, это решение работает исключительно хорошо — я могу отправлять изображения меньшего размера примерно за десять секунд, но когда я начал тестировать большие файлы и экспериментировать с разным FPS, я понял, что терминальному приложению не хватает частоты кадров QR-кода. для тестирования более высоких скоростей передачи, и приложение может зависнуть, если вы вручную выполните тест с высокой частотой кадров.
TXQR-тест
Если я хочу найти оптимальное сочетание FPS, размера кадра QR-кода и уровня восстановления QR-кода, мне нужно запустить не менее 1000 тестов, вручную настроить параметры и записать результаты в форму, а также продолжать держать телефон у экрана. . Слишком много проблем, никак. Очевидно, я должен автоматизировать этот шаг.
Поэтому мне нужно тестовое приложение txqr. Во-первых, я решил использовать UI-фреймворк настольного приложения, реализованный на языке Go.x/exp/shiny, но это все еще казалось экспериментальным фреймворком, поэтому я его забросил. Обидно, потому что я пытался использовать его год назадshiny
, в то время это было многообещающе для простых настольных приложений. Но когда я пытаюсь использовать его сейчас, он даже не компилируется. Кажется, что нет особого стимула для разработки фреймворков пользовательского интерфейса для настольных компьютеров, потому что большинство приложений теперь находятся в Интернете.
Но веб-программирование все еще находится на ранних стадиях развития — браузеры только начинают поддерживать другие языки программирования через WASM, но это только начало. Конечно, вы можете использовать JavaScript, но как друг я все еще не рекомендую использовать JavaScript для написания веб-приложений, поэтому я решил использовать недавно обнаруженный проект —VectyFramework, так что вы можете писать интерфейсный код на Go и работать над очень зрелым проектом.GopherJSАвтоматически компилируется в JS.
Vecty и GopherJS
Честно говоря, я никогда раньше не получал такого удовольствия от написания внешнего кода.
Я буду писать в блоге гораздо больше о своем недавнем опыте работы с Vecty, включая разработку приложений WebGL и т. д., но важно то, что после написания нескольких проектов с React, Angulars и Ember я могу использовать сложный язык дизайна для реализовать этот проект действительно чувство, как увидеть солнце! Теперь я могу иметь хорошее веб-приложение, не написав ни единой строки JavaScript, и в большинстве случаев «оно действительно работает»!
Шучу, вот как написать веб-приложение на Go сегодня:
package main
import (
"github.com/gopherjs/vecty"
)
func main() {
app := NewApp()
vecty.SetTitle("My App")
vecty.AddStylesheet(/* ... add your css... */)
vecty.RenderBody(app)
}
Приложение представляет собой тип встроенногоvecty.Core
структура типа - и должна реализовать интерфейсvecty.Component
. Вот и все! Инициализация объектов DOM поначалу может показаться многословной, но когда вы начинаете рефакторинг своего кода, становится ясно, насколько он мощный:
// App 是一个顶层的应用组建
type App struct {
vecty.Core
session *Session
settings *Settings
// any other stuff you need,
// it's just a struct
}
// Render 实现了接口 vecty.Component
func (a *App) Render() vecty.ComponentOrHTML {
return elem.Body(
a.header(),
elem.Div(
vecty.Markup(
vecty.Class("columns"),
),
// 左半边
elem.Div(
vecty.Markup(
vecty.Class("column", "is-half"),
),
elem.Div(a.QR()), // 二维码显示区域
),
// 右半边
elem.Div(
vecty.Markup(
vecty.Class("column", "is-half"),
),
vecty.If(!a.session.Started(), elem.Div(
a.settings,
)),
vecty.If(a.session.Started(), elem.Div(
a.resultsTable,
)),
),
),
vecty.Markup(
event.KeyDown(a.KeyListener),
),
)
}
Вы можете смотреть на этот код и думать, что он очень многословен, я признаю, что это так, но процесс написания кода — это радость! Нет необходимости в HTML-тегах начала/конца, это очень простая операция копирования и вставки (если вы хотите переместить некоторые узлы DOM), структура кода очень понятна, читабельность относительно высока, и он строго типизирован! Уверяю вас, когда вы начнете писать свои собственные компоненты, вам будет очень полезна его многословность.
Люди думают, что Vecty — это React-подобный проект, но это не так. Для GopherjS действительно есть привязки к React —myitcv.io/react, но я не думаю, что нам нужно следовать тому же подходу, что и React. Когда вы пишете внешний интерфейс с помощью Vecty, вы понимаете, что на самом деле все очень просто. Вам не нужно скрытое расширенное использование и новые функции, созданные большинством фреймворков JavaScript — это лишь некоторые из более сложных вещей. Вам просто нужны типы, функции и методы, комбинируйте их и вызывайте в нужное время.
Что касается CSS, я использую очень полезный CSS-фреймворк.Bulma- Он предоставляет несколько логически ясных и осмысленных имен, что делает скомпилированный код пользовательского интерфейса очень читаемым.
Однако самая волшебная часть — это этап компиляции. вам просто нужно бежатьgopherjs build
, и менее чем за секунду вы получите скомпилированный JS-код, который можно использовать как ссылку на страницу или серверную службу. Когда я запускал его в первый раз, я ожидал кучу ошибок, предупреждений или нечитаемых сообщений, но этого не произошло — он был очень быстрым, делал все молча и просто показывал несколько ошибок компиляции в одной строке. Кстати, на стороне браузера, если выдается ошибка, вы можете увидеть трассировку стека, связанную с файлом Go (не скомпилированным файлом JS), а также увидеть номер строки кода. Это супер круто?
Проверить параметры кодирования TXQR
Вот и все, через несколько часов у меня есть веб-приложение, позволяющее настроить диапазон параметров теста:
- FPS (кадры в секунду)
- Объем кадра QR-кода (сколько битов может содержаться в каждом кадре QR-кода)
- Уровень восстановления QR-кода (низкий, средний, высокий или самый высокий)
Затем можно инициализировать тестовую программу мобильного приложения.
Конечно, мобильное приложение также должно быть автоматизировано — приложение должно быть в состоянии определить, когда начинается следующий этап тестирования, обрабатывать тайм-ауты (иногда камера телефона не получает все кадры и, следовательно, результаты) и отправить результаты в приложение и т. д.
Одной из наиболее проблемных частей является то, что веб-приложение не может создать прослушивающий сокет — оно запускается в браузере, и для такого простого протокола проверки связи, кроме использования WebRTC (что я не считаю нужным), можно только действовать как клиент, использовать, но не создавать.
Решение на самом деле довольно простое — небольшое приложение Go, которое может служить статическим HTTP-сервером для веб-приложения (и может автоматически обслуживать функции браузера), а также может включать прокси-сервер WebSocket, который ожидает только два подключения — от пользовательского интерфейса (или веб-приложение) и подключения с мобильной стороны — это прозрачный прокси, с точки зрения двух клиентов их можно рассматривать как передачу информации напрямую. Конечно, они должны быть в сети WiFi.
Также нужно придумать способ передать адрес WebSocket в мобильное приложение, угадайте, что можно сделать с помощью QR-кода :) Итак, рабочий процесс выглядит следующим образом:
- Мобильное приложение ищет метку «старт» в QR-коде.
- Начните с тега, извлеките URL-адрес «ws://» и подключитесь к службе по этому адресу.
- Приложение пользовательского интерфейса немедленно распознает соединение и начинает генерировать следующий этап тестирования QR-кода.
- Отображение нового QR-кода с пометкой «readyToStart?»
- Мобильный терминал считывает QR-код и отправляет информацию для подтверждения через WebSocket.
Таким образом, в конце концов, мне просто нужно положить мобильный телефон на полку, позволить ему отправлять информацию, сканируя QR-код, и отправлять информацию и приложение для связи друг с другом через WebSocket.
Пользовательский интерфейс терминала поддерживает загрузку CSV-файла, на основе которого его можно проанализировать с помощью R или других статистических инструментов и языков.
Ориентиры
Полный тестовый цикл длился около 4 часов (самая трудоемкая часть - генерация динамического QR-кода выполнялась в браузере, все еще с использованием JS, он использовал только одно ядро процессора), мне также нужно было убедиться, что экран не закрывается , или другие окна приложения не охватывают тестовое приложение. Я настроил тест со следующими параметрами:
- FPS- от 3 до 12
- Объем кадра QR-кода- от 100 до 1000 (с шагом 30)
- Уровень восстановления QR-кода- Все уровни, всего 4
- объем данных- 13 КБ (данные представляют собой случайно сгенерированные двоичные байты)
Через несколько часов я скачал CSV-файл и провел быстрый анализ и визуализацию.
результат
Изображение стоит тысячи слов, а трехмерный интерактивный виджет может предоставить тысячу изображений. Ниже приведен 3D-график рассеяния результатов тестового сбора данных:
Лучший результат — 1,4 секунды, что составляет почти 9 КБ/с! Результирующая скорость составляет 11 кадров в секунду, размер блока — 850 байт, используется средний уровень восстановления. На самом деле, при такой скорости кодирования и частоте кадров вероятность того, что камера телефона пропустит кадры, очень высока, поэтому много раз приложение просто продолжает зацикливаться, ожидая пропущенных кадров, пока время тестового цикла не истечет.
Ниже приведена гистограмма изменения размера блока данных и частоты кадров (обратите внимание, что время истечения здесь составляет 30 с):
Размер блока времени и данных:
Как показано на рисунке выше, меньший размер блока данных приведет к тому, что накладные расходы на кодирование QR-кода будут слишком большими, а общее время резко возрастет. Разумные значения — 550 и 900 байт на блок, но более высокие или меньшие байты вызовут тайм-ауты из-за потерянных кадров. При размере 1000 байт мы почти наверняка потеряем кадры и вызовем тайм-аут.
Время и FPS:
К моему удивлению, параметр FPS не оказал большого влияния на результаты. Лучшим значением кажется 6-7 кадров в секунду, что примерно соответствует интервалу кадров в 150 мс. Более низкая частота кадров приводит к увеличению задержки, а более высокая частота кадров приводит к пропущенным кадрам.
Уровень восстановления времени и QR-кода
Существует сильная корреляция между параметром уровня восстановления QR-кода и временем передачи и уровнем избыточности, очевидно, что лучший выбор - более низкий уровень восстановления (7% избыточности), без сомнения - меньше избыточных данных легче читать, и QR-коды меньше, что упрощает их сканирование и идентификацию. Для передачи данных нам, вероятно, не нужна большая избыточность. Таким образом, лучшее значение может быть средним или низким.
Чтобы получить более подробные выводы, эти тестовые циклы, вероятно, следует запускать сотни раз на разных экранах и устройствах. Но для моих исследований и разработок в эти выходные этого было достаточно.
в заключении
Этот интересный проект доказал мне, что односторонняя передача данных абсолютно возможна без подключения к интернету, просто с помощью динамических QR-кодов. Причем максимальная скорость передачи данных составляет около 9Кб/с, а средняя скорость в большинстве случаев - 1-2Кб/с.
В то же время использование Gomobile и Gopherjs (одновременно с Vecty) дало мне очень хороший и эффективный опыт разработки — они почти стали моими ежедневными инструментами разработки. Это зрелые фреймворки, которые работают быстро и дают вам опыт «действительно работает».
И последнее, но не менее важное: с Go вы можете значительно повысить свою производительность, которая всегда казалась мне удивительной, когда вы знаете, что вам нужно построить — дополнительные короткие циклы выполнения редактирования могут облегчить тестирование, простой код и отсутствие сумасшедшего наследования классов. , что делает рефакторинг простой и плавной работой, а идея кросс-платформенного дизайна позволяет повторно использовать один и тот же код на сервере, веб-приложении и мобильном приложении одновременно. При этом места для оптимизации и ускорения очень много, просто я сделал работу самым прямым образом.
Если вы никогда не пробовали gomobile или gopherjs — предлагаю вам попробовать. На изучение у вас уйдет около часа, но вы откроете дверь в мир, где вы сможете разрабатывать веб-сайты или мобильные устройства с помощью Go. Иди попробуй!
Ссылка на ссылку
- github.com/divan/txqr
- GitHub.com/divan/sex lover/…
- GitHub.com/divan/sex lover-…
- GitHub.com/divan/sex lover-…
- GitHub.com/gopher — это просто/VE…
- GitHub.com/golang/mobi…
возобновить
Обновление: txqr теперь использует более эффективный метод, т.е.фонтан двор.последующие статьиЕсть подробные объяснения и сравнения результатов тестов, и вы можете просмотреть их, если вам интересно.
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллекти другие поля, если вы хотите видеть больше качественных переводов, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.