WebSocket: Простейший функционал на сервере Glassfish 4
Поиск по сайту:
О разработчеке сайта
Header image

Новые статьи и уроки JAVA

WebSocket: Простейший функционал на сервере Glassfish 4

Спустя почти год после опубликования последней статьи и обещания рассказать о реализации веб-сокетов я, наконец-то, волевым решением выделил время на столь приятное для меня и полезное для Вас занятие.

Эта статья открывает серию уроков, посвященных реализации такого невероятно полезного механизма как websocket средствами сервера GlassFish. В отличии от серии статей JavaEE здесь не будет сквозного примера у первых уроков. Далее по мере увеличения сложности и изученных возможностей возможно реализуем что-нибудь серьезное, чтобы объеденить в себе весь функционал технологии веб-сокетов.

Если Вы прочли все статьи серии JAVA EE и реализовали указанные там примеры, то далее можете приступать к изучению без замедления т.к. все необходимые для понимания уроков знания у Вас уже есть.

1

Если же Вы еще слабо знакомы с Java EE или не работали с сервером приложение GlassFish, тогда вам помогут статьи:

JAVA EE: Разработка web-приложения. Подготовка, чтобы узнать как настраивать сервер приложений GlassFish и БД MySql.

JAVA EE: Разработка web-приложения. Дизайн и настройка, чтобы узнать как настраивать IDE NetBeans для работы и создать каркас приложения.

JAVA EE: Разработка web-приложения. View и Controller, чтобы разобраться как работает в Java EE паттерн MVC и получить минимально необходимый набор знаний для реализации примеров этой серии статей.

Поговорим о том зачем нужны эти самые websocket'ы.

 Представим такую ситуацию: вам необходимо активно обмениваться с сервером некоторыми данными и на их основе формировать какие-то действия на клиентской стороне программы, причем вы подвязаны на события и данные, происходящие именно на сервере и вам нужно оперативно о них узнавать и что-то предпринимать. Вы не знаете когда и в каком виде произойдет событие на сервере, но узнать о нем и его результатах нужно максимально оперативно.

Например, сообщить клиенту о том, что ему пришло личное сообщение или уведомление, или закончилась длительная обработка пакета файлов, или это вовсе онлайн-игрушка и нужно постоянно получать данные о некторых событиях (вспышка справа, выстрел слева, солнце село).

Лично я представляю 3 варианта решения подобной задачи не прибегая к помощи технологии flash или java апплетов:

  • Ajax. Постояный, рекурсивный или по таймеру опрос сервера на наличие изменений. Такой вариант для каждого запроса открывает новое соединение с сервером, что его нагружает. При "грамотном" подходе можно 3-мя посетителями положить сервер на лопатки и заставить его страдать. Оперативность получения информации о событии на сервере зависит от частоты опроса и удачи клиента. Мы не можем узнать о событии ровно в момент его происхождения, только в один из шагов опроса сервера.
  • IFrame. Если Вы истинный Мсье и знаете толк в извращениях, то это же можно реализовать при помощи замудренных Ifram'ов. В общем IFrame - это

    1только для истинных ценителей.

  • WebSoked. Да, да, именно наш websoked. Сплошные плюсы: асинхронность, малая нагрузка на сервер, двустороний вызов событий передачи данных, что делает процесс получения данных максимально оперативным.

С приходом WebSoсked html перестал быть однонаправленным, теперь данные можно получать не только по инициативе клиента, но и по инициативе сервера.

 В этой статье мы реализуем минимально возможный функционал веб-сокетов. Этакий легковесный аналог ajax., т.к. по сути клиент будет вызывать событие обмена данными, а не сервер. Однако этого функционала более чем достаточно для понимания работы веб-сокетов на сервере GlassFish.

Реализация серверной части. Слушатели и обработчики.

 Итак, запускаем NetBeans, и создаем веб-приложение ws_lesson1.

Новое веб-приложение

 Создаем класс websocked. В нем у нас и будет весь функционал сервера.

Создаем новый класс websocked

 Теперь нам необходимо зарегистрировать слушателя websocked'a на сервере и указать адрес, по которому он будет находиться. Все это мы сделаем одной короткой строкой. Как? Да так же как и раньше, при помощи аннотаций!

Добавьте перед объявлением класса аннотацию: @ServerEndpoint("/websocket").

Этой аннотацией мы автоматически зарегистрировали этот класс в сервере как слушателя websoked. Параметром в аннотации мы указал url адрес, по которому слушатель будет принимать соединение относильно корневого адреса проекта (именно проекта, а не домена).

import javax.websocket.server.ServerEndpoint;

/**
 *
 * @author a.egorov
 */
@ServerEndpoint("/websocket")
public class websocket {}

IDE поможет добавить вам в импорт класс ServerEndPoint.

В теле класса необходимо реализовать функции событий: открытия соединения, закрытия соединения, получения сообщения и вылета ошибки.

@ServerEndpoint("/websocket")
public class websocket {
   
    @OnOpen
    public void eventOpen(){
        System.out.println("Соединение установленно...");
    }
   
    @OnClose
    public void eventClose(){
        System.out.println("Соединение закрыто");
    }
   
    @OnMessage
    public String EventMessage(String message){
        System.out.println("Получено сообщение от клиента:"+message);
        String reply="Ваше сообщение: "+message+" было полученно;";
        return reply;
    }
   
    @OnError
    public void eventError(Throwable t){
        System.err.println("Error WebSocket");
    }
   
}

Для привязки функций к событиям используются соотвествующие аннотации перед объявлением функций @OnOpen, @OnClose, @OnMessage, @OnError.

IDE предложит Вам добавить классы, соотвествующие аннотациям, не отказывайте ей (это же она, да? :) ) в этом удовольствие.

На открытие и закрытие соединения мы в этом примере только выводим информацию в консоль.

Событие OnMessage происходит при получении сообщения от клиента и возращает ответ клиенту. В нашем случае за это событие отвечает функция EventMessage.

На этом серверная часть закончена. Неожиданно правда? Минимум кода, максимум продуктивности.

Клиентская часть. Создание объекта WebSocked, подключение к серверу и обмен данными.

Откроем файл index.html и добавим туда 3 элемента: поля для ввода сообщения, кнопку отправки и поле логирования процессов.

 

 <input type="text" id="message" />
        <input value="Отправить" onclick="sendMessage();" type="button"/>
        <hr/>
        <textarea readonly="readonly" id="messages" rows="15" cols="60"></textarea>

 

На событие "нажатие кнопки отправки сообщения" привязали функцию sendMessage.

Далее пишем javascprit код и внимательно читаем комментарии:

<script type="text/javascript">
            /*создаем объект WebSocked и указываем путь для подключения.
            * Подключение произойдет сразу после создания компонента.
            */
            var webSocket = new WebSocket("ws://localhost:9090/ws_lesson1/websocket");
            var messages=document.getElementById("messages");
            var message=document.getElementById("message");
            //обработчик события открытия соединения с сервером
            webSocket.onopen=function(message){
                messages.value+="Соединение установлено \n";
            };
            //обработчик события закрытия соединения с сервером
            webSocket.onclose=function(message){
                messages.value+="Соединение закрыто \n";
            }
            //обработчик ошибки при работе с сокетом.
            webSocket.onerror=function (message){
                messages.value+="Произошла ошибка \n";
            }
            //обработчик нажатия кнопки отправки сообщения
            function sendMessage(){
                //отправляем сообщение на сервер
                webSocket.send(message.value);
                messages.value+="На сервер отправлено:>"+message.value+" \n";
                message.value="";
            }
            //обработчик получения сообщения ОТ сервера.
            webSocket.onmessage=function(message){
                messages.value+="Получено сообщение от сервера: "+message.data+" \n";
            }
        </script>

Из комментария к коду можно понять  все, что происходит в коде: создание компонента, объявление слушателей и обработка результатов.

Можно развертывать приложение, наслаждаться результатом.

 Вот так легко и просто мы реализовали простейший механиз веб-сокетов. Его явный минус в том, что пока мы не можем выборочно рассылать сообщения клиентам, инициализированные сервером, только отвечать на запросы клиента. Однако даже такой вот механизм значительно экономит ресурсы сервера в отличии от ajax запросов.

В следующем уроке мы будем инициализировать сервером массовую рассылку сообщений различным пользователям.

1Важно. Комментарии на кириллице пока сервером воспринимаются болезненно, за выходные постараюсь исправить. Пока просьба писать в транслите или на английском.

1 Все налажено. Комментарии работают.

19.12.2014

Комментарии

Spasibo za post! Nujnaya infa!

24.12.2014 Автор: NA

Пожалуйста! Пользуйтесь)

12.03.2015 Автор: Анатолий

Картинок не видно: This image failed to load

21.01.2015 Автор: Davinchi

Да, вы правы. Но они в контексте данной статьи и не столь важны. Вся соль в исходниках.

12.03.2015 Автор: Анатолий

спасибо огромное за классные статьи, все бы так объясняли. Будет просьба-пишите больше, эти статьи прекрасны, все доходчиво и интересно.Очень бы хотелось прочитать статью про самые современные тенденции в java разработке- что сейчас применяют.

01.03.2015 Автор: Илья

Спасибо за добрые отзывы о моей работе)

Когда я в свое время начинал знакомиться с JavaEE, я был неприятно удивлен тому что в рунете не было практически никакой информации о базовых принципах работы данной технологии. Все статьи что я находил, как правило, были оторваными друг от друга, там перечеслялись различные технологии, а о том как их заставить работать вместе и что из этого будет ни слова.
Все статьи были написаны профессионалами и для профессионалов, тем самым порог вхождения в данную технологию был не оправдано высок.

Учитывая все это, я понял что могу уменьшить ту брешь в рунете которую, почему, никто не хотел замечать. Я начал писать данные статьи с целью уменьшить порог и время вхождения новых программистов в JavaEE. Худо-бедно мне это удалось.

Статьи про передовые технологии в Java как раз относятся уже к разряду "профи статей", а еще так много не написано про более простые возможности.

У самого меня последние два года, по различным причинам, совсем нет времени на написание статей. В новый год успел написать статью про websocked и никак не могу дописать вторую часть хотя для нее уже все готово, нужно только оформить.

Однако, саму идею и сайт я не бросаю и все равно продолжу писать статьи :)

12.03.2015 Автор: Анатолий

СПАСИБИЩЕ !!!

25.11.2016 Автор: Dimon

Спасибо, ждем продолжения !!!

13.02.2017 Автор: Andrey

Очень интересно почитать продолжение. Буду благодарен за статью.

26.02.2017 Автор: Mihalich

На пороге 2018 год, а статей уже как 4 года нет)

Но не суть...

Многоуважаемый автор,

скачал проект, пытался своим скудным умом и кривыми ручками смастерить сам,

но появляется ошибка...

GlassFish Server 4.1, deploy, null, false
C:\Users\matyushenkois\Downloads\MyBlog-article9\MyBlog-article9\myblog\nbproject\build-impl.xml:1070: Модуль не развернут.
Подробные сведения приведены в протоколе сервера.
СБОРКА ЗАВЕРШЕНА СО СБОЕМ (общее время: 1 секунда)

 

как и что сделать не понимаю, ПРОШУ помочь.

сама строка: 

1069 <target if="netbeans.home" name="-run-deploy-nb">
1070        <nbdeploy clientUrlPart="${client.urlPart}" debugmode="false" forceRedeploy="${forceRedeploy}"/>
    1071 </target>

13.12.2017 Автор: Игорь