Comments 34
Также, непонятно, зачем изобретать свой протокол, когда в Ява есть уже стандартный вариант, библиотеки для него, инструменты.
Хотелось бы понять, конечно.
У вебсокета асинхронная двусторонняя связь — push нотификации. Он работает по http — не требуется дополнительной настройки сетевых экранов. Добавляем https и мы не видны для антивирусов — по умолчанию они не сканируют защищенный канал (некоторые блокируют ответ от сервера по незащищенному каналу). Установка клиента на рабочее место заключается в простом копировании ярлыка, который скачивает бинарники и без дополнительных настроек запускает клиента. Ранее использовалась технология RMI, которая работала на сокете по определенному порту и требовался администратор для установки на новое рабочее место. Так как к окружению применялись высокие требования безопасности, то все порты кроме 80 были закрыты по умолчанию.
Возможно, если бы я писал высоконагруженное приложение, то отказался бы от javaee и ее серверов приложений, воспользовался бы пакетом java.nio и написал бы еще одну реализацию веб-сокетов, но она была бы лучше.
На стороне java-сервера крутится javaee — сервер приложений, с готовой реализацией веб-сокетов. Библиотека, которую он использует предлагает готовый веб-сокет клиент. В моем случае нецелесообразно было вестись на мнимую производительность собственного кода и обременять себя поддержкой еще и сокетных решений.
Про ярлык и скачивание бинарников клиента к веб-сокетам никакого отношения не имеет — все верно. Это косвенно касается темы статьи про простую поддержку, в которую входит также настройка рабочего места для клиента. Описанный подход позволил эту настройку свести к простому копированию ярлыка и его запуску.
Не читал статью, но хочу сказать, что вебсокеты вполне можно использовать вместо обычных сокетов, оверхед фактически только на подключение, дальше идёт очень простой бинарный протокол вида <размер пакета><данные>, что все равно придется придумывать для обычных
Задачи интеграции с js-клиентом и обменом json не ставилось.
Если не ошибаюсь, есть проблема, когда у тебя Date лежит в Map. Приходится что-то дополнительно прописывать, а то он дату сериализует в число, а обратно, не может понять к чему это число привести.
Я в работе, по привычке использую JodaTime, плюс никогда не перевожу в-из json непосредственно в бизнес-сущности, у меня всегда есть промежуточное звено назначение которого как раз в конвертации. Позволяет держать нутро «не осведомленным» о том, что его в какой-то момент времени будут конвертировать и представлять в json, или обратно.
Объявляются интерфейсы для сервисов. Далее их реализация может быть распределенной. Все интерфейсы доступны. При вызове любого метода ищется сперва локальный бин, а если его нет динамическим прокси дергается тот же метод удаленно.
Еще надо бы Service Discovery впилить, но руки не доходят пока.
Согласен с предыдущими комментаторами. Если нужна двусторонняя связь проще просто на сокетах, а не втаскивать вебсокеты.
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
слишком много надо было менять в инфраструктуре серверного кода (вот такая вот заменяемость контейнеров в javaee)
— сделать приложение не переносимым, это заслуга разработчика/архитектора, технология тут не виновата. Если в кроссплатформенной Java написать:
File f = new File("C:/myfile.txt");
она тоже перестанет быть кроссплатформенной, но это не значит что виновата технология. Во всяком случае на JavaEE можно писать приложения с минимальными модификациями при переносе, если об этом побеспокоиться изначально.
// server side
MyService serv = new MyService();
Endpoint.publish("http://localhost:9000/", serv);
// client
QName portQName = new QName("my", "MyServiceService");
Service service = Service.create(new URL("http://localhost:9090/services/hello?wsdl"), portQName);
IService client = service.getPort(IService.class);
System.out.println(client.echo("hello"));
@WebService(name = "MyService", targetNamespace = "my")
public interface IService {
String echo(String s);
}
Привык делать так, чтобы не отвлекаться на подобные ситуации. Одно дело, когда только сам используешь для себя, другое дело еще всем коллегам надо помнить о том, что где-то надо что-то подписать. По моему опыту этого никто не помнит, а когда выстреливает, то тратится большое количество времени на решение проблемы.
Джавовский RMI в его основе — это совсем не про то, как клиенту что-то вызвать на сервере через Java Proxy. RMI — это распределенная сеть, там нет ни сервера, ни клиента, есть только peer-s. Любой Remote-объект может быть передан по сети любому из peer-ов точно также как и обычный, например в качестве параметра к удаленному методу или поля объекта. При реализации истинного RMI вам придется решать такие задачи как call-routig, call-forwarding, service discovery, и distributed garbage collector.
Может быть то, что вы хотели сделать, уже существует?
Ну как это никто не пишет? Даже джавовский почти стандартный Jersey умеет уже давно проксировать клиента. Причем один и тот же аннотированный интерфейс можно использовать как для клиента, так и для сервиса.
@Stateless
или @Singleton
) реализовывал интерфейс и имел определенное имя. Этого достаточно, чтобы его можно было вызвать с клиента через proxy.Просто и очень удобно.
Возможно, но обмен сериализованными объектами средствами java не вызывает никаких проблем, а главное требует минимум с точки зрения кода — реализацию интерфейса маркера Serializable
и, если не ошибаюсь, то конструктор по умолчанию.
Максимально простой в поддержке способ интеграции java-клиента с java-сервером