Server java client javascript

WebSocket tutorial with Java server (Jetty) and JavaScript client

WebSocket is a web technology providing full-duplex communications channels over a single TCP connection. WebSocket is designed to be implemented in web browsers and web servers, but it can be used by any client or server application. In this tutorial we will use a Java server and a JavaScript client.

We start with the Java server. Start by downloading the Jetty distribution files, at the time of writing the latest version was jetty-distribution-9.0.5.v20130815. Unzip this file and copy the lib directory to a place where your Java application (which we will build in a moment) can find it. Now create a Java project and start with the WebSocketTest class file:

import org.eclipse.jetty.server.Server; import org.eclipse.jetty.websocket.server.WebSocketHandler; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; public class WebSocketTest < public static void main(String[] args) throws Exception < Server server = new Server(8080); WebSocketHandler wsHandler = new WebSocketHandler() < @Override public void configure(WebSocketServletFactory factory) < factory.register(MyWebSocketHandler.class); >>; server.setHandler(wsHandler); server.start(); server.join(); > >

Now create the MyWebSocketHandler class:

import java.io.IOException; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; @WebSocket public class MyWebSocketHandler < @OnWebSocketClose public void onClose(int statusCode, String reason) < System.out.println("Close: statusCode=" + statusCode + ", reason=" + reason); >@OnWebSocketError public void onError(Throwable t) < System.out.println("Error: " + t.getMessage()); >@OnWebSocketConnect public void onConnect(Session session) < System.out.println("Connect: " + session.getRemoteAddress().getAddress()); try < session.getRemote().sendString("Hello Webbrowser"); >catch (IOException e) < e.printStackTrace(); >> @OnWebSocketMessage public void onMessage(String message) < System.out.println("Message: " + message); >>

The server side of things is now done. The client is written in Javascript with some HTML to make it work. The index.html file looks like this:

And the referenced index.js looks like this:

var ws = new WebSocket("ws://127.0.0.1:8080/"); ws.onopen = function() < alert("Opened!"); ws.send("Hello Server"); >; ws.onmessage = function (evt) < alert("Message: " + evt.data); >; ws.onclose = function() < alert("Closed!"); >; ws.onerror = function(err) < alert("Error: " + err); >;

Now startup the server side by running the main of the WebSocketTest class and startup the client by pointing your webbrowser to the index.html file. If your browser is new enough to support WebSocket, you should see that the client and the server connect with each other and that the server sends a message to the client and vice versa. On the client:

Читайте также:  Adding python path variable

websocket-client-1 websocket-client-2

websocket-server-1

If we wait long enough, a timeout will occur, resulting in the following message on the client:

websocket-client-3

websocket-server-2

Источник

WebSocket: Реализация web-приложения с использованием Jetty Web Socket. Часть 1

Поздравляю всех и каждого с великим Днем Программиста! Желаю рабочего кода, уверенных сокетов и самых продвинутых пользователей!

Работая над автоматизацией концертного агентства, мне на каком-то этапе разработки понадобилась система уведомлений. Доступ к автоматизации происходит через написанное мною web-приложение. И, соответственно, моментальные уведомления должны приходить в браузер пользователя.

  • браузер отправляет запрос каждую секунду создавая лишнюю нагрузку на:
    • сервер;
    • ОС, на которой работает браузер;
    • и еще раз на сервер, так как сервер постоянно выполняет запрос БД на выборку последних уведомлений.

    Среди минусов WebSocket важен только тот, что его пока поддерживают только браузеры webkit (они же Google Chrome и Apple Safari).

    Давайте попробуем реализовать простой чат, как web-приложение c базовой возможностью полнодуплексного обмена сообщениями между клиентом и сервером.

    Реализация клиентской части

    Реализация WebSocket-ов на JavaScript на клиентской стороне простая, на неё не будем тратить много времени. Смотрим листинг.

    var socket = new WebSocket("ws://myserver.com:8081/"); socket.onopen = function () < console.log("Соединение открылось"); >; socket.onclose = function () < console.log ("Соединение закрылось"); >; socket.onmessage = function (event) < console.log ("Пришло сообщение с содержанием:", event.data); >; 

    Отправлять сообщения на сервер можно методом send():
    socket.send(messageString);

    Реализация серверной части

    Что мы имеем? Давайте взглянем на схему.

    схема взаимодействия браузера, glassfish и jetty

    В моем случае мы имеем контейнер сервлетов GlassFish на порту 8080. Браузер отправляет запрос на GlassFish [1], который передает браузеру страничку чата [2], которая по желанию пользователя соединяется с сервером через порт 8081 по протоколу WebSocket [3]. Далее происходит полнодуплексный обмен данными между браузером и сервером [4].

    • jetty-continuation-8.0.1.v20110908.jar,
    • jetty-http-8.0.1.v20110908.jar,
    • jetty-io-8.0.1.v20110908.jar,
    • jetty-server-8.0.1.v20110908.jar,
    • jetty-util-8.0.1.v20110908.jar,
    • jetty-websocket-8.0.1.v20110908.jar.

    Возвращаясь к клиентской части, скачиваем ее отсюда (не хочу засорять пост листингом HTML-кода). Добавляем файл chat.html в Web Pages проекта. В дескрипторе развёртывания (web.xml) указываем chat.html как «welcome-file».

    Embedded-сервер Jetty находится в классе org.eclipse.jetty.server.Server. И конструктор может содержать либо адрес сервера, либо, как в нашем случае номер порта:

    Server jetty = new Server(8081);

    Далее нам нужно добавить в jetty нужные handlerы и запустить его. Запускается и останавливается jetty методами без параметров start() и stop() соответственно. А вот handler нам надо будет написать свой, создаем новый класс. Чтобы у нас был handler для обработки соединений по протоколу WebSocket, мы должны его наследовать от org.eclipse.jetty.websocket.WebSocketHandler:

    public class ChatWebSocketHandler extends WebSocketHandler …
    >
    У класса WebSocketHandler есть один абстрактный метод doWebSocketConnect(). Он, собственно, и вызывается, когда браузер открывает новое соединение с jetty, и возвращает объект WebSocketа.

    • onOpen() – вызывается после открытия сокета;
    • onClose() – вызывается перед закрытием сокета;
    • onMessage() – вызывается когда приходит сообщение от клиента.
    • 1 свойство – набор сокетов;
    • 1 метод, который нам создает и возвращает новый сокет;
    • 1 приватный класс, который реализует этот WebSocket.

    Что из себя представляет протокол обмена?

    • /auth ник //Для авторизации
    • /getUsers //Для получения списка пользователей
    • /help //Для получения помощи
    • inf|информация // Пришла информация
    • in|ник|сообщение // Входящее сообщение от пользователя ник
    • out|сообщение // Мое сообщение отправлено
    • err|ошибка // Пришла информация об ошибке

    Теперь перейдем к самому ответственному моменту — запуск сервера jetty. Значит, у нас задача: при старте контейнера сервлетов запустить jetty; перед остановкой контейнера сервлетов — остановить jetty. Самый простой способ это реализовать в GlassFish — написать свой ContextListener. Давайте посмотрим почему? Создаем новый класс и наследуем его от интерфейса javax.servlet.ServletContextListener. Смотрим листинг.

    import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.DefaultHandler; public class ChatServerServletContextListener implements ServletContextListener < /** * Хранилище сервера Jetty */ private Server server = null; /** * Метод вызывается когда контейнер сервлетов запускается * @param event */ @Override public void contextInitialized(ServletContextEvent event) < try < // Создание сервера Jetty на 8081 порту this.server = new Server(8081); // Регистрируем ChatWebSocketHandler в сервере Jetty ChatWebSocketHandler chatWebSocketHandler = new ChatWebSocketHandler(); // Это вариант хэндлера для WebSocketHandlerContainer chatWebSocketHandler.setHandler(new DefaultHandler()); // Вставляем наш хэндлер слушаться jetty server.setHandler(chatWebSocketHandler); // Запускаем Jetty server.start(); >catch (Throwable e) < e.printStackTrace(); >> /** * Метод вызывается когда контейнер сервлетов останавливается * @param event */ @Override public void contextDestroyed(ServletContextEvent event) < // Если сервер jetty когда-нибудь запустился if (server != null) < try < // останавливаем Jetty server.stop(); >catch (Exception e) < e.printStackTrace(); >> > > 

    Интерфейс javax.servlet.ServletContextListener имеет два метода с говорящими самими за себя именами: contextInitialized(), contextDestroyed().

    Теперь нам остается только подключить наш ContextListener в дескриптор развёртывания (web.xml). Приведу его листинг:

        30  chat.html  ChatServerServletContextListener   

    Ну теперь можно и запустить проект. В браузере открываем сразу два окна и балуемся. Прошу обратить внимание на время, сообщения доходят практически моментально. Такую скорость работы на ajax получить практически невозможно.

    image

    image

    Заключение

    Весь проект в сборе можно скачать по ссылке
    Проект полностью совместим с GlassFish 2.x, 3.x и Tomcat не ниже 5.0. Проект создавал в Netbeans 7.0.1. Внутри проекта можно найти ant-deploy.xml для развертки на Ant. Еще раз дико извиняюсь перед разработчиками, использующих Maven.

    Во второй части статьи я подробно опишу проблемы, которые возникают при работе с WebSocket, и их решения.
    В третьей части я опишу способы борьбы с ddos-атаками на серверы Jetty.

    Спасибо за внимание. Всех еще раз с праздником!

    Источник

    Читайте также:  Анимация круглой кнопки css
Оцените статью