Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Работа с сетью > WebSocket (Java сервер) Какие есть способы? |
Автор: ZVano 28.10.2015, 11:59 |
Прежде всего - мой уровень в Java нулевой. Пришлось заняться в связи с войной браузеров. Задача: Нужно из браузерного JavaScript вызывать функции *.dll, *.so (ЭЦП, работа с оборудованием, работа с принтером) Раньше этим занимался JavaApplet, но в связи с отказом содателей браузеров от поддержки NPAPI они перестали работать (в Chrome Java уже не работает, в Mozilla Firefox перестанет работать через год). Идея решения такова: 1. Написать Java-приложение, которое будет запускаться через JNLS (Java Web Start). 2. Java-приложение должно уметь работать с dll. 3. Java-приложение должно открывать порт для чтения HTTP-трафика (обеспечивать серверную сторону WebSocket). 4. Написать код JavaScript, который будет обращаться к Java-приложению через WebSocket. Т.е. загрузили Web-страницу, вызвали загрузку JNLP. После этого пуляем JSON через WebSocket и получаем асинхронные ответы. Вопросы: Как реализовать п3? Подозреваю что в JDK должно быть готовое решение, но я его не нашел - все примеры используют Tomcat или GlassFish. Есть рабочий пример UploadServer, который может принимать файлы по HTTP. Взят отсюда http://www.denvo.ru/pub/programming/upload-server.html и запилен в проект NetBeans 8 (по умолчанию висит на порту 8011). Но тут прийдется анализировать заголовки, извлекать из "грязного" текста нужное мне тело пакета (данные в формате JSON). Прошу сориентировать в этом вопросе. Может есть простой готовый класс основанный на событиях. Произошло событие "пишли данные" в параметре data лежит тело пакета, а в параметре headers HTTP заголовки. Может первичная задача вообще решается не так, как я думаю. |
Автор: LSD 28.10.2015, 12:23 |
Зачем вам вообще веб часть при наличии полноценного десктоп приложения? |
Автор: ZVano 28.10.2015, 12:37 |
Потому что уже написаны мегатонны кода и никто переделывать его не будет. Техзадание было на Web-приложение. |
Автор: LSD 28.10.2015, 16:57 |
Disclaimer: то что вы пытаетесь реализовать это извращение с кучей подводных камней (типа как обойти фаервол, где и как смотреть логи и т.п.). И лучше все таки изменить архитектуру, хотя бы показывать приложение внутри https://www.teamdev.com/jxbrowser (или в чем-то подобном). Если же надо именно реализовать вебсервер, то надо просто взять готовую реализацию вебсервера. Например https://github.com/NanoHttpd/nanohttpd, и написать свои обработчики событий. |
Автор: LSD 29.10.2015, 14:12 | ||
Так это просто ключ на флешке или токен который сам все подписывает? It depends... - Кто использует приложение - внутренние или внешние клиенты. - На каких ОС и браузерах оно используется и можно ли сократить этот круг. - Планируется ли дальнейшее активное развитие приложения. |
Автор: ZVano 29.10.2015, 16:19 | ||||
Токен. "Кристалл 1" http://eu.iit.com.ua/ и пример JavaApplet http://sign.eu.iit.com.ua/ Не забываем что кроме ЭЦП есть еще обращение к железякам через dll. В основном внешние.
ОС Windows для спецмодулей и любые другие для остального. Браузеров зоопарк и они забиты в ТЗ. Я не знаю. Это только руководству известно. |
Автор: LSD 30.10.2015, 15:52 |
В принципе тогда вариантов действительно немного. Или локальный вебсервер или приложение. Мне лично больше нравится вариант с веб браузера внутри Java приложения, т.к.: 1. Тут нет сетевого взаимодействия и нет риска что будет проблемы с сетью из-за фаервола или cross origin request. 2. Диагностика проще, Java приложение может собирать логи свои и вебстраницы и любую дополнительную информацию. 3. Фиксированная версия браузера. 4. Приложение может предоставлять больше функций чем вебстраничка внутри браузера. Нотификации, работа в офлайне, более продвинутая работа с файлами и т.п. |
Автор: ZVano 30.10.2015, 16:39 | ||
А как в этом случае использовать уже существующий код, который крутится на внешнем Web-сервере? Апплеты будут работать в Java-browser? С куками он умеет работать? JavaScriprt работает? Возможности HTML5 поддерживает? |
Автор: LSD 30.10.2015, 17:52 |
Вопрос только в том какую использовать реализацию.
|
Автор: ZVano 30.10.2015, 18:21 |
LSD, спасибо. Буду читать и щупать. Есть еще год до момента "П...ц" (извините за мой французский ![]() |
Автор: Sajtran 31.10.2015, 15:24 |
мда, проблема действительно доступ к локали компа всё больше обрывается через WEB плагинами только к кажому браузеру отдельно если и это не перекроют без вариантов, кроме как писать на старый добрый десктоп Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/WebSocket-(Java-server)-Kakiye-est-sposoby-id56308e94ae2015ee118b4567#findElement_E7045_5634b309ae2015f372887414_0 |
Автор: ZVano 6.6.2016, 16:33 |
Внимание! Не тратьте время на тупиковую ветвь. Этот подход не будет работать, если Ваш Web-ресурс (с которого запускается JNLP) находится под HTTPSом. Браузер будет блокировать все HTTP, HTTPS, WS и WSS запросы к ресурсу с self-signed сертификатом. Нормальный сертификат для localhost Вы не получите даже за деньги. Вы никак не обойдете это ограничение Т.е. Вы не сможете присоединиться из JAVA-script к локальному WebApi-сервису на Java. Правда, можно руками добавить сертификат в список доверенных в браузере - тогда будет работать (но это совсем не феншуйно). Если же Ваш Web-ресурс работает по HTTP, то подход работоспособен и весьма удобен в использовании. PS: Безусловно блокируются фоновые запросы (выводится ошибка в консоль браузера). Если же ссылку ввести в поле URL браузера, то он(браузер) выдаст страницу с предупреждением и даст возможность добавить сертификат в список доверенных. |
Автор: LSD 7.6.2016, 13:01 | ||||
А кто мешает в hosts прописать
? |
Автор: ZVano 7.6.2016, 14:33 |
Никто не мешает. Но это снова изменения руками. Причем нужно обладать соответствующими правами. Когда я писал "Вы никак не обойдете это ограничение" подразумевалось что решение не будет работать без ручного вмешательства. (Другое решение этой проблемы - написать в инструкции пользователя "Наберите в строке URL значение https://127.0.0.1:2016 и примите сертификат, который вам предложат со страшными предупреждениями") Представьте себе ситуацию - пользователям https://forum.vingrad.ru нужно добавить строчку в hosts чтобы зайти на сайт. Много было бы таких отважных? Причем тут собрались умные люди. |
Автор: LSD 7.6.2016, 15:14 |
Я думал это для тестов нужно. А зачем нужно JavaScript-у соединяться с localhost? Да еще обязательно по HTTPS? От каких таких атак предполагается защищаться HTTPS-ом? |
Автор: ZVano 7.6.2016, 15:27 | ||
Основной сайт на HTTPSе (Apache+PHP >> HTML+JavaScript). Ему нужно выполнять функции, которыми раньше занимался JavaApplet (сейчас апплеты не работают). Для этого на Java сделана отдельная приблуда. Она запускается на том же компьютере, где работает браузер. JavaScript обращается к ней, а она решает задачи, которые невозможно сделать средствами JavaScript. http://iit.com.ua/download/productfiles/EUSignAgentD.pdf См. Рисунок 1.1
Защищаться не нужно. Просто браузер блокирует HTTP запросы, если страница загружена по HTTPS. На этом я и погорел. DEV и TEST на HTTP. Поэтому прога прошла тестирование. Выкатили на PROD - не работает. |
Автор: LSD 7.6.2016, 17:54 | ||
Хочу напомнить, что я говорил в прошлом году:
Что же касается твоей ситуации, то можно попробовать следующее: получить сертификат на некий свой поддомен: local-api.my-site.com, в DNS для этого хоста прописать 127.0.0.1 (так можно делать). Ну и дальше слать запросы на этот хост. Но тут есть ГИГАНТСКАЯ проблема: сервер который крутится локально у клиента должен содержать секретный ключ из сертификата. Единственный способ, как-то минимизировать ущерб, это получить от СЦ ключ с правом подписи других ключей. Для каждого клиента генерировать случайный поддомен и уникальный ключ для него, без права подписи и минимальным сроком жизни. Но возможно тут тоже будут грабли которые пока не видны в траве. |
Автор: ZVano 8.6.2016, 09:07 | ||
cross origin то я победил. А вот с SSL... Ну что поделаешь, не знал я. По незнанию и наступил на грабли.
Обговорил этот вопрос с нашим админом. Он сказал решительное нет. Спасибо за идею. Покумекаем. В данный момент идем другим путем. А именно, создаем WebSocket на основном сайте. Он будет выступать в роли поседника, к которому будут цепляться браузеры и их вспомогательные утилиты. Таким образом проблемы должны разрешиться. |
Автор: LSD 8.8.2016, 16:47 | ||
В продолжении темы, https://habrahabr.ru/company/aladdinrd/blog/306920/ люди пошли тем же путем.
|
Автор: ZVano 16.11.2017, 13:50 |
В итоге мы вернулись к первоначальному решению и оно уже год работает нормально (за исключением мути с самоподписными сертификатами, таки не дали мне нормальных). Сделал так же альтернативный вариант с WS|WSS WebSocket сервером-посредником. Однако посмотрев сколько лишнего трафика генерируется, насколько неустойчивой и сложной в отладке получилась система, отказались от этого решения (хоть оно и рабочее). |