Работа сотрудника банка опасна и трудна. В Единой фронтальной системе мы стараемся помочь сотруднику банка и автоматизировать его работу. Одна из многочисленных задач, которую нам нужно решить, — доработать тонкий клиент для возможности работы с периферийным банковским оборудованием. Но сделать это не так-то просто. В данной статье мы расскажем, как мы пытались решить задачу, и к чему это привело.
Статья будет полезна архитекторам и опытным front-end разработчикам систем масштаба предприятий, столкнувшихся с проблемой доступа к периферийному оборудованию из тонкого клиента своей системы.
И да, скажем сразу, задача усложняется тем, что стандартные подходы с применением ActiveX, Java Applet, плагина браузера нас не устраивают по соображениям безопасности, универсальности и сложностей с управляемостью и сопровождаемостью.
Представьте себе скромный (по китайским меркам) банк, в отделениях которого работают более 100 тыс. операторов. У них есть рабочие места, на которых они обслуживают клиентов, а к рабочим местам подключены различные периферийные устройства:
- Сетевой/локальный принтер.
- Чековый принтер (Epson-M950 или Olivetti).
- POS-терминал (Verifone VX820).
- Устройство для чтения «таблеток» (touch memory с ЭЦП).
- Сканеры разных типов (для штрих-кодов, паспортов или просто документов).
- Веб-камера (фотографировать потенциальных заемщиков).
- Специфическое банковское оборудование – cash dispenser/receiver и т.п.
Внушительный список, не правда ли? И со всем этим нужно взаимодействовать из работающего в браузере react-приложения.
Работа с устройствами на низком уровне осуществляется через драйвера производителей оборудования или native библиотеки внутренней разработки. Установка и обновление драйверов и другого ПО на рабочих местах осуществляются централизованно. На рабочих местах стоят Windows и Internet Explorer 11 или 8. Обсуждается возможность перехода на Linux и Chrome/Firefox. Отсюда возникает требование кросс-платформенности и кросс-браузерности.
Проблема разнородности устройств и их отказов более-менее решена, но требуется мониторинг работы устройств, включая возможность забирать логи с рабочего места. Также требуется централизованное управление настройками работы с периферией.
Требования безопасности заключаются в контроле целостности кода, запускаемого на клиенте, ограничении доступа к периферии (доступ должен быть только с локального рабочего места) и ряда специфичных требований к работе с touch memory.
Отдельный вопрос – работа планшета с периферией. Идея в том, чтобы заменить компьютеры на мобильные девайсы, перенеся на них весь функционал оператора, включая совершение банковских операций. В этой статье мы не будем подробно говорить про планшеты, обязательно расскажем об этом в другой статье, просто обозначим, что здесь возникают как вопросы подключения самого планшета к внутренней банковской сети по wi-fi, так и вопросы работы с устройствами, подключаемыми непосредственно к планшету, например, mPOS-терминалами.
Как мы пытались все это приручить, почему не сразу получилось
Из условий эксплуатации следует схема работы с периферией:
Мы попытались найти решение проблемы и проработали несколько вариантов.
HTML5
Хотя в нем потенциально есть работа с периферийными устройствами, текущие реализации заточены под мобильные устройства или аудио/видео, и для наших задач не подходят от слова «совсем».
WebUSB
https://wicg.github.io/webusb/ — во-первых, не все устройства подключаются через USB. Во-вторых, поддержки WebUSB на текущий момент нет нигде, кроме экспериментальной feature в Chrome. Так что тоже нам не подходит.
ActiveX
Способ старинный и проверенный – делаются обертки над драйверами, устанавливаемые как локальные OCX или DLL, обращение к которым идет через ActiveXObject:
var printer = new ActiveXObject("LocalPrinterComponent.Printer");
printer.print(data + "rn");
Но он работает только в IE и Windows. Несмотря на попытки сделать технологию ActiveX переносимой, Microsoft отказалась от развития ActiveX в пользу технологии плагинов.
Плагины браузера
Это тоже нам не подходит, не является целевым, привязывает к браузеру и ограничивает универсальность.
Нативные компоненты на Java
На localhost выставляется cервис, который доступен из JavaScript. От этого тоже решили отказаться, т.к. реализация более трудоемкая, требуется использовать веб-сервер либо писать свой.
Applet
Не целевой, возникают проблемы с правами доступа на локальном устройстве.
И что же делать?
В итоге мы остановились на следующей архитектуре работы с периферийными устройствами:
Клиентское приложение в JavaScript обращается к локальному сервису через модуль работы с периферийным API, который является обвязкой над клиентской частью socket.io.
На рабочие места устанавливается node.js, который запускается под сервисной учетной записью при старте операционки. В node.js работает наш модуль bootstrap, отвечающий за загрузку npm-модулей для работы с периферийными устройствами с сервера в локальную файловую систему. Клиентский код генерирует event, в качестве атрибутов передается код и версия модуля, который работает с устройством, вызываемый метод и его параметры:
Также bootstrap отвечает за работу с платформенными сервисами (выгрузку логов с рабочего места по запросу администратора и т.п.)
Для каждого периферийного устройства имеется свой модуль работы с ним, исполняемый в node.js. Bootstrap проксирует вызов в метод модуля:
Модуль работает с низкоуровневым API операционной системы или драйвера через npm модуль node.js «ffi»:
Когда клиентское приложение обращается к bootstrap, передавая модуль и версию, bootstrap проверяет локальное хранилище. Если нужного модуля нет в локальном хранилище, он выкачивается его с сервера. Таким образом, централизованно устанавливаются только драйвера и node.js с bootstrap’ом, а npm-модули для работы с устройствами скачиваются в рантайме. Но данная функция вряд ли будет использоваться в промышленной конфигурации, так что предполагаем, что при удаленной инсталляции драйверов устройств на рабочие места сотрудников будет устанавливаться и соответствующий npm модуль периферийного API, представляющий собой JS bundle.
Решение пока еще не реализовано, мы работаем над этим и обязательно расскажем о результатах в другой статье. А пока хотим спросить у вас, что вы думаете о выбранном подходе? Какие подводные камни нас ждут? Приглашаем всех принять участие в дискуссии в комментариях.
Автор: EFS_programm