Использование WebSocket API в веб-приложении

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

Из этого учебного курса вы узнаете о том, как создать веб-приложение, использующее интерфейс Java API for WebSocket (JSR 356) для двустороннего обмена данными между браузерными клиентами и сервером приложений. Интерфейс Java API for WebSocket обеспечивает возможность создания компонентов Java WebSocket, инициализации и перехвата событий WebSocket, а также создания и использования текстовых и двоичных сообщений WebSocket. В этом учебном курсе также приведен пример использования интерфейса Java API for JSON Processing (JSR 353) для создания и использования компонентов JSON. Интерфейсы Java API for WebSocket и Java API for JSON Processing являются компонентами платформы Java EE 7 (JSR 342).

Приложение содержит интерфейсы WebSocket для терминала, декодера и кодера, веб-страницу и ряд файлов JavaScript, запускаемых в браузере клиента при загрузке страницы или вызываемых формой на веб-странице. Развертывание приложения осуществляется на экземпляре GlassFish Server Open Source Edition 4, эталонной версии реализации технологии Java EE 7.

Примечание. Этот курс основывается на статье блога Collaborative Whiteboard using WebSocket in GlassFish 4 - Text/JSON and Binary/ArrayBuffer Data Transfer (TOTD #189) и других статьях блога Arun Gupta. Рекомендуем посетить этот блог и ознакомиться с другими интересными статьями о работе с WebSocket API и GlassFish 4.

Также рекомендуем посмотреть видеоролик Использование WebSocket API в веб-приложении.

Упражнения по темам руководства

Содержимое на этой странице применимо к IDE NetBeans 7.3, 7.4 и 8.0

Для работы с этим учебным курсом требуется следующее программное обеспечение и ресурсы.

Программное обеспечение или ресурс Требуемая версия
IDE NetBeans Версия Java EE 7.3.1, 7.4, 8.0
Комплект для разработчика на языке Java (JDK) версия 7 или 8
GlassFish Server Open Source Edition 3.1.2.2 4

Примечание. GlassFish 4 входит в состав загружаемого комплекта Java EE для NetBeans IDE.

Предпосылки

Предполагается, что читатель обладает базовыми знаниями по следующим технологиям или опытом программирования с их использованием:

  • Программирование на Java
  • Программирование на JavaScript/HTML
  • IDE NetBeans

Перед изучением этого учебного курса можно ознакомиться со следующей документацией:

Можно загрузить готовый проект в виде архива ZIP.

Создание проекта веб-приложения

Цель этого упражнения - создать проект веб-приложения с помощью мастера создания проектов в IDE. При создании проекта в качестве версии Java EE необходимо указать Java EE 7, а в качестве сервера приложений - GlassFish 4. GlassFish 4 является эталонной реализацией платформы Java EE 7. Для создания приложения по инструкциям, приведенным в этом учебном курсе, вам потребуется сервер приложений с поддержкой Java EE 7, зарегистрированный в IDE.

  1. Выберите Файл > Создать проект в главном меню (в Windows можно использовать сочетание клавиш Ctrl-Shift-N; в Mac - сочетание клавиш ⌘-Shift-N).
  2. Выберите в категории Maven пункт "Веб-приложение". Нажмите 'Далее'.
  3. В поле 'Имя проекта' введите WhiteboardApp и укажите местоположение проекта.
  4. В поле 'ИД группы' введите org.sample. Нажмите 'Далее'.
  5. В списке 'Сервер' выберите GlassFish Server 4.0.
  6. В списке 'Версия Java EE' выберите Java EE 7 Web. Нажмите 'Готово'.
    Сведения о проекте в мастере создания проектов

При нажатии кнопки "Завершить" проект будет создан в среде IDE, который откроется в окне "Проекты".

Создание терминала WebSocket

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

Дополнительные сведения об использовании API-интерфейсов и аннотаций WebSocket см. в описании пакета javax.websocket.

Создание терминала

В этом упражнении показано, как создать класс терминала WebSocket с помощью мастера IDE.

  1. В окне 'Проекты' щелкните правой кнопкой мыши узел 'Исходные пакеты' и выберите 'Создать > Другие'.
  2. В категории 'Веб' выберите 'Терминал WebSocket'. Нажмите 'Далее'.
  3. В поле 'Имя класса' введите MyWhiteboard.
  4. В списке 'Пакет' выберите org.sample.whiteboardapp.
  5. В поле 'WebSocket URI' введите /whiteboardendpoint. Нажмите 'Готово'.
    Терминал WebSocket в мастере создания файлов

    При нажатии кнопки 'Готово' среда IDE создает класс терминала WebSocket и открывает файл в редакторе исходного кода. При просмотре файла в редакторе вы увидите, что среда IDE сгенерировала несколько аннотаций, которые входят в состав API-интерфейса WebSocket. Класс имеет аннотацию @ServerEndpoint, указывающую на его принадлежность к классам терминала, а в качестве параметра аннотации указан WebSocket URI. Среда IDE также создает стандартный метод onMessage с аннотацией @OnMessage. Метод с аннотацией @OnMessage вызывается каждый раз, когда клиент получает сообщение WebSocket.

    @ServerEndpoint("/whiteboardendpoint")
    public class MyWhiteboard {
    
        @OnMessage
        public String onMessage(String message) {
            return null;
        }
        
    }
  6. Добавьте в класс следующее поле (выделено полужирным шрифтом).
    @ServerEndpoint("/whiteboardendpoint")
    public class MyWhiteboard {
        private static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());
    
        @OnMessage
        public String onMessage(String message) {
            return null;
        }
    }
  7. Добавьте методы onOpen и onClose.
        @OnOpen
        public void onOpen (Session peer) {
            peers.add(peer);
        }
    
        @OnClose
        public void onClose (Session peer) {
            peers.remove(peer);
        }

    Методы onOpen и onClose имеют аннотации API-интерфейса WebSocket: @OnOpen и @OnClose. Метод с аннотацией @OnOpen вызывается при открытии сеанса WebSocket. В этом примере аннотированный метод onOpen добавляет браузерного клиента в группу одноранговых узлов текущего сеанса, а метод onClose удаляет клиента из этой группы.

    Создайте методы, используя подсказки и автозавершение кода в редакторе исходного кода. Щелкните значок подсказки в левом поле рядом с объявлением класса (или поместите указатель мыши на объявление класса и нажмите Alt-Enter), затем выберите этот метод в раскрывающемся меню. Для создания кода метода можно использовать автозавершение кода.

    снимок экрана - Подсказка к коду в редакторе исходного кода
  8. Щелкните правой кнопкой мыши в редакторе и выберите 'Исправить операторы импорта' (Alt-Shift-I; ⌘-Shift-I для Mac). Сохраните изменения.

    В результате в файл будут добавлены операторы импорта для классов в javax.websocket.

Терминал создан. Теперь необходимо создать файл JavaScript для инициализации сеанса WebSocket.

Инициализация сеанса WebSocket

Этот раздел содержит инструкции по созданию файла JavaScript для инициализации сеанса WebSocket. Браузерный клиент подключается к сеансу, используя HTTP-запрос для квитирования с сервером по протоколу TCP. В файле JavaScript необходимо указать wsURI терминала и объявить WebSocket. Схема wsURI является составным элементом протокола WebSocket и указывает путь к терминалу для приложения.

  1. Щелкните правой кнопкой мыши узел проекта в окне "Проекты" и выберите "New > Other"(Создать > Другое).
  2. Откройте мастер создания файлов и выберите 'Файл JavaScript' в категории 'Веб'. Нажмите 'Далее'.
  3. В поле 'Имя файла JavaScript' введите websocket. Нажмите 'Готово'.
  4. Добавьте в файл JavaScript следующие элементы.
    var wsUri = "ws://" + document.location.host + document.location.pathname + "whiteboardendpoint";
    var websocket = new WebSocket(wsUri);
    
    websocket.onerror = function(evt) { onError(evt) };
    
    function onError(evt) {
        writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
    }

    Этот сценарий инициализирует квитирование сеанса с сервером, когда браузер загружает файл websocket.js.

  5. Откройте файл index.html и добавьте следующий код (выделен полужирным шрифтом) в самый нижний сегмент файла, чтобы по завершении загрузки страницы загружался файл websocket.js.
    <body>
        <h1>Collaborative Whiteboard App</h1>
            
        <script type="text/javascript" src="websocket.js"></script>
    </body>

Теперь можно проверить функционирование терминала WebSocket, возможность открытия сеанса и подключения клиента к сеансу.

Тестирование терминала

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

  1. Добавьте тег <div> (выделен полужирным шрифтом) в файл index.html
    <h1>Collaborative Whiteboard App</h1>
            
    <div id="output"></div>
    <script type="text/javascript" src="websocket.js"></script>
  2. Добавьте следующее объявление и методы в файл websocket.js. Сохраните изменения.
    // For testing purposes
    var output = document.getElementById("output");
    websocket.onopen = function(evt) { onOpen(evt) };
    
    function writeToScreen(message) {
        output.innerHTML += message + "<br>";
    }
    
    function onOpen() {
        writeToScreen("Connected to " + wsUri);
    }
    // End test functions

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

  3. Правой кнопкой мыши щелкните окно 'Проект' и выберите 'Выполнить'.

При запуске приложения среда IDE запускает сервер GlassFish и выполняет построение и развертывание приложения. В браузере открывается страница индекса со следующим сообщением.

Сообщение 'Подключение к терминалу установлено' в окне браузера

В окне браузера отображается терминал, принимающий сообщения: http://localhost:8080/WhiteboardApp/whiteboardendpoint

Создание интерактивной доски

Этот раздел содержит инструкции по созданию классов и файлов JavaScript для отправки и получения текстовых сообщений JSON. Также в этом разделе показано, как создать элемент HTML5 Canvas для рисования и отображения содержимого и HTML-форму <form> с переключателями, с помощью которых можно выбрать форму и цвет кисти.

Добавление полотна на веб-страницу

В этом упражнении показано, как добавить элемент canvas и элемент form на страницу индекса по умолчанию. Флажки на форме определяют свойства кисти на полотне.

  1. Откройте файл index.html в редакторе исходного кода.
  2. Удалите тег <div>, добавленный перед тестированием терминала, и добавьте элементы <table> и <form> (выделены полужирным шрифтом) после открывающего тега body.
    <h1>Collaborative Whiteboard App</h1>
            
        <table>
            <tr>
                <td>
                </td>
                <td>
                    <form name="inputForm">
                        
    
                    </form>
                </td>
            </tr>
        </table>
        <script type="text/javascript" src="websocket.js"></script>
        </body>
  3. Добавьте следующий код (выделен полужирным шрифтом) для элемента canvas.
            <table>
                <tr>
                    <td>
                        <canvas id="myCanvas" width="150" height="150" style="border:1px solid #000000;"></canvas>
                    </td>
  4. Добавьте элемент <table> для создания переключателей, позволяющих выбирать цвет и форму. Сохраните изменения.
            <table>
                <tr>
                    <td>
                        <canvas id="myCanvas" width="150" height="150" style="border:1px solid #000000;"></canvas>
                    </td>
                    <td>
                        <form name="inputForm">
                            <table>
    
                                <tr>
                                    <th>Color</th>
                                    <td><input type="radio" name="color" value="#FF0000" checked="true">Red</td>
                                    <td><input type="radio" name="color" value="#0000FF">Blue</td>
                                    <td><input type="radio" name="color" value="#FF9900">Orange</td>
                                    <td><input type="radio" name="color" value="#33CC33">Green</td>
                                </tr>
    
                                <tr>
                                    <th>Shape</th>
                                    <td><input type="radio" name="shape" value="square" checked="true">Square</td>
                                    <td><input type="radio" name="shape" value="circle">Circle</td>
                                    <td> </td>
                                    <td> </td>
                                </tr>
    
                            </table>
                        </form>

    Форма, цвет и координаты любой фигуры, нарисованной на полотне, преобразуются в строковые данные в структуре JSON и отправляются в виде сообщения на терминал WebSocket.

Создание POJO

В этом упражнении показано, как создать простой компонент POJO.

  1. Щелкните узел проекта правой кнопкой мыши и выберите Создать > Класс Java.
  2. В поле 'Имя класса' введите Figure и выберите org.sample.whiteboardapp в списке 'Пакет'. Нажмите 'Готово'.
  3. В редакторе исходного кода добавьте следующие элементы (выделены полужирным шрифтом):
    public class Figure {
        private JsonObject json;
    }

    При добавлении кода отобразится запрос на добавление оператора импорта для javax.json.JsonObject. Если запрос не отображается, нажмите Alt-Enter.

    Дополнительные сведения о javax.json.JsonObject см. в описании интерфейса Java API for JSON Processing (JSR 353), который входит в спецификацию Java EE 7.

  4. Создайте операторы получения и установки для json.

    Методы получения и установки можно выбрать в раскрывающемся меню 'Вставить код' (Alt-Ins в Windows; Ctrl-I в Mac). В результате откроется диалоговое окно 'Создание методов получения и установки'. Также можно выбрать Исходный код > Вставить код в главном меню.

    Диалоговое окно 'Создание методов получения и установки'
  5. Добавьте конструктор для json.
        public Figure(JsonObject json) {
            this.json = json;
        }

    Конструктор можно выбрать в раскрывающемся меню 'Вставить код' (Ctrl-I).

    Раскрывающееся меню 'Создать конструктор'
  6. Добавьте метод toString:
        @Override
        public String toString() {
            StringWriter writer = new StringWriter();
            Json.createWriter(writer).write(json);
            return writer.toString();
        }
  7. Щелкните правой кнопкой мыши в редакторе и выберите 'Исправить операторы импорта' (Alt-Shift-I; ⌘-Shift-I для Mac). Сохраните изменения.

Создание класса координат

Теперь необходимо создать класс координат фигур, которые пользователи будут рисовать на полотне.

  1. Щелкните узел проекта правой кнопкой мыши и выберите Создать > Класс Java.
  2. Откроется мастер создания классов Java. В поле 'Имя класса' введите Coordinates и выберите org.sample.whiteboardapp в списке 'Пакет'. Нажмите 'Готово'.
  3. В редакторе исходного кода добавьте следующий код. Сохраните изменения.
        private float x;
        private float y;
    
        public Coordinates() {
        }
    
        public Coordinates(float x, float y) {
            this.x = x;
            this.y = y;
        }
    
        public float getX() {
            return x;
        }
    
        public void setX(float x) {
            this.x = x;
        }
    
        public float getY() {
            return y;
        }
    
        public void setY(float y) {
            this.y = y;
        }
                    

Этот класс содержит только поля для координат x и y, а также несколько методов получения и установки.

Создание строки JSON

В этом упражнении показано, как создать файл JavaScript, преобразующий все сведения о фигуре, которую пользователь рисует на полотне (элемент canvas), в структуру JSON для отправки на терминал WebSocket.

  1. Щелкните узел проекта правой кнопкой мыши и выберите Создать > Файл JavaScript. В результате откроется мастер создания файлов JavaScript.
  2. В поле 'Имя файла' введите whiteboard. Нажмите 'Готово'.

    При нажатии кнопки 'Готово' среда IDE создает пустой файл JavaScript и открывает его в редакторе. Новый файл отображается в структуре узла 'Веб-страницы' в окне 'Проекты'.

  3. Добавьте следующий код для инициализации элемента canvas и создания прослушивателя событий.
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
    canvas.addEventListener("click", defineImage, false);

    Когда пользователь нажимает на полотно (элемент canvas), вызывается метод defineImage.

  4. Добавьте методы getCurrentPos, defineImage и drawImageText для создания структуры JSON и ее отправки на терминал (sendText(json)).
    function getCurrentPos(evt) {
        var rect = canvas.getBoundingClientRect();
        return {
            x: evt.clientX - rect.left,
            y: evt.clientY - rect.top
        };
    }
                
    function defineImage(evt) {
        var currentPos = getCurrentPos(evt);
        
        for (i = 0; i < document.inputForm.color.length; i++) {
            if (document.inputForm.color[i].checked) {
                var color = document.inputForm.color[i];
                break;
            }
        }
                
        for (i = 0; i < document.inputForm.shape.length; i++) {
            if (document.inputForm.shape[i].checked) {
                var shape = document.inputForm.shape[i];
                break;
            }
        }
        
        var json = JSON.stringify({
            "shape": shape.value,
            "color": color.value,
            "coords": {
                "x": currentPos.x,
                "y": currentPos.y
            }
        });
        drawImageText(json);
            sendText(json);
    }
    
    function drawImageText(image) {
        console.log("drawImageText");
        var json = JSON.parse(image);
        context.fillStyle = json.color;
        switch (json.shape) {
        case "circle":
            context.beginPath();
            context.arc(json.coords.x, json.coords.y, 5, 0, 2 * Math.PI, false);
            context.fill();
            break;
        case "square":
        default:
            context.fillRect(json.coords.x, json.coords.y, 10, 10);
            break;
        }
    }

    Готовая к отправке структура JSON будет выглядеть примерно так:

    {
     "shape": "square",
     "color": "#FF0000",
     "coords": {
     "x": 31.59999942779541,
     "y": 49.91999053955078
     }
    } 

    Теперь необходимо добавить метод sendText(json) для отправки строковых данных JSON с помощью websocket.send().

  5. Откройте файл websocket.js в редакторе и добавьте следующие методы для отправки JSON на терминал и рисования изображения при получении сообщения от терминала.
    websocket.onmessage = function(evt) { onMessage(evt) };
    
    function sendText(json) {
        console.log("sending text: " + json);
        websocket.send(json);
    }
                    
    function onMessage(evt) {
        console.log("received: " + evt.data);
        drawImageText(evt.data);
    }

    Примечание. Код, добавленный в файл websocket.js для тестирования терминала, можно удалить.

  6. Добавьте следующую строку (выделена полужирным шрифтом) в нижний сегмент файла index.html для загрузки файла whiteboard.js.
            </table>
        <script type="text/javascript" src="websocket.js"></script>
        <script type="text/javascript" src="whiteboard.js"></script>
    <body>
                    

Реализация интерфейсов кодера и декодера

В этом упражнении показано, как создать классы для реализации интерфейсов декодера и кодера, которые требуются для преобразования сообщений WebSocket (JSON) в класс POJO Figure и преобразования класса Figure в формат строковых данных JSON, отправляемых на терминал.

Дополнительные сведения можно найти в разделе технической статьи о типах сообщений, кодерах и декодерах JSR 356, Java API for WebSocket.

  1. Щелкните узел проекта правой кнопкой мыши и выберите Создать > Класс Java.
  2. В поле 'Имя класса' введите FigureEncoder и выберите org.sample.whiteboardapp в списке 'Пакет'. Нажмите 'Готово'.
  3. В редакторе исходного кода реализуйте интерфейс кодера WebSocket. Для этого добавьте следующий код (выделен полужирным шрифтом):
                
    public class FigureEncoder implements Encoder.Text<Figure> {
        
    }
  4. Добавьте оператор импорта для javax.websocket.Encoder и реализуйте абстрактные методы.

    Поместите указатель мыши на объявление класса, нажмите Alt-Enter и выберите Реализовать все абстрактные методы в раскрывающемся меню.

  5. Внесите следующие изменения в созданные абстрактные методы (выделены полужирным шрифтом). Сохраните изменения.
        @Override
        public String encode(Figure figure) throws EncodeException {
            return figure.getJson().toString();
        }
    
        @Override
        public void init(EndpointConfig ec) {
            System.out.println("init");
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy");
        }
  6. Щелкните узел проекта правой кнопкой мыши и выберите Создать > Класс Java.
  7. В поле 'Имя класса' введите FigureDecoder и выберите org.sample.whiteboardapp в списке 'Пакет'. Нажмите 'Готово'.
  8. В редакторе исходного кода реализуйте интерфейс декодера WebSocket. Для этого добавьте следующий код (выделен полужирным шрифтом):
                
    public class FigureDecoder implements Decoder.Text<Figure> {
        
    }
  9. Добавьте оператор импорта для javax.websocket.Decoder и реализуйте абстрактные методы.
  10. Внесите следующие изменения (выделены полужирным шрифтом) в созданные абстрактные методы.
        @Override
        public Figure decode(String string) throws DecodeException {
            JsonObject jsonObject = Json.createReader(new StringReader(string)).readObject();
            return  new Figure(jsonObject);
        }
    
        @Override
        public boolean willDecode(String string) {
            try {
                Json.createReader(new StringReader(string)).readObject();
                return true;
            } catch (JsonException ex) {
                ex.printStackTrace();
                return false;
            }
        
        }
    
        @Override
        public void init(EndpointConfig ec) {
            System.out.println("init");
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy");
        }
  11. Исправьте операторы импорта и сохраните изменения.

Теперь необходимо внести изменения в файл MyWhiteboard.java и указать кодер и декодер.

Запуск приложения

Скоро вы сможете запустить приложение. В этом упражнении показано, как изменить класс терминала WebSocket и указать кодер и декодер для строковых данных JSON, а также добавить метод для отправки строковых данных JSON на подключенные клиенты при получении сообщения.

  1. Откройте файл MyWhiteboard.java в редакторе.
  2. Измените аннотацию @ServerEndpoint и укажите кодер и декодер для терминала. Обратите внимание, что необходимо явно указать параметр value для имени терминала.
    @ServerEndpoint(value="/whiteboardendpoint", encoders = {FigureEncoder.class}, decoders = {FigureDecoder.class})
            
  3. Удалите метод onMessage, созданный по умолчанию.
  4. Добавьте метод broadcastFigure и создайте для него аннотацию @OnMessage.
        @OnMessage
        public void broadcastFigure(Figure figure, Session session) throws IOException, EncodeException {
            System.out.println("broadcastFigure: " + figure);
            for (Session peer : peers) {
                if (!peer.equals(session)) {
                    peer.getBasicRemote().sendObject(figure);
                }
            }
        }
  5. Щелкните правой кнопкой мыши в редакторе и выберите 'Исправить операторы импорта' (Alt-Shift-I; ⌘-Shift-I для Mac). Сохраните изменения.
  6. В окне 'Проекты' щелкните проект правой кнопкой мыши и выберите 'Выполнить'.

При нажатии кнопки 'Выполнить' среда IDE открывает окно браузера с адресом http://localhost:8080/WhiteboardApp/.

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

Просмотрите сообщения браузера. Вы увидите, что при каждом нажатии на полотно на терминал отправляются строковые данные JSON.

снимок приложения в окне браузера

Если открыть страницу с адресом http://localhost:8080/WhiteboardApp/ в другом браузере, можно видеть, что при каждом нажатии на полотно в окне одного браузера в окне другого браузера появляется новый круг или квадрат.

снимок приложения, открытого в двух браузерах

Отправка двоичных данных на терминал

Теперь приложение может обрабатывать и отправлять строковые данные через JSON на терминал, а затем эти строковые данные будут пересылаться на подключенные клиенты. Этот раздел содержит инструкции по изменению файлов JavaScript для отправки и получения двоичных данных.

Чтобы отправлять двоичные данные на терминал, необходимо задать для свойства binaryType компонента WebSocket значение arraybuffer. Таким образом гарантируется, что любые двоичные данные, передаваемые посредством WebSocket, передаются посредством ArrayBuffer. Преобразование двоичных данных осуществляется методом defineImageBinary в файле whiteboard.js.

  1. Откройте файл websocket.js и добавьте в него следующий код, чтобы задать для свойства binaryType компонента WebSocket значение arraybuffer.
    websocket.binaryType = "arraybuffer";
  2. Добавьте следующий метод для отправки двоичных данных на терминал.
    function sendBinary(bytes) {
        console.log("sending binary: " + Object.prototype.toString.call(bytes));
        websocket.send(bytes);
    }
  3. Измените метод onMessage и добавьте в него следующий код (выделен полужирным шрифтом), чтобы выбрать метод обновления полотна в соответствии с типом данных, переданных во входящем сообщении.
    function onMessage(evt) {
        console.log("received: " + evt.data);
        if (typeof evt.data == "string") {
            drawImageText(evt.data);
        } else {
            drawImageBinary(evt.data);
        }
    }

    Метод drawImageBinary вызывается при получении сообщения с двоичными данными.

  4. Откройте файл whiteboard.js и добавьте следующие методы. Метод drawImageBinary вызывается для обновления полотна после анализа входных двоичных данных. Метод defineImageBinary используется для подготовки снимка полотна в двоичном формате.
    function drawImageBinary(blob) {
        var bytes = new Uint8Array(blob);
    //    console.log('drawImageBinary (bytes.length): ' + bytes.length);
        
        var imageData = context.createImageData(canvas.width, canvas.height);
        
        for (var i=8; i<imageData.data.length; i++) {
            imageData.data[i] = bytes[i];
        }
        context.putImageData(imageData, 0, 0);
        
        var img = document.createElement('img');
        img.height = canvas.height;
        img.width = canvas.width;
        img.src = canvas.toDataURL();
    }
                        
    function defineImageBinary() {
        var image = context.getImageData(0, 0, canvas.width, canvas.height);
        var buffer = new ArrayBuffer(image.data.length);
        var bytes = new Uint8Array(buffer);
        for (var i=0; i<bytes.length; i++) {
            bytes[i] = image.data[i];
        }
        sendBinary(buffer);
    }

    Теперь необходимо реализовать вызов метода defineImageBinary, когда требуется сгенерировать двоичные данные с типом ArrayBuffer и отправить их на терминал.

  5. Откройте файл index.html и измените элемент <table> так, чтобы в таблице формы появилась следующая строка.
    <tr>
        <th> </th>
        <td><input type="submit" value="Send Snapshot" onclick="defineImageBinary(); return false;"></td>
        <td> </td>
        <td> </td>
        <td> </td>
    </tr>
                    

    Новая строка содержит кнопку 'Отправить снимок', которая позволяет отправить двоичный снимок полотна на подключенные одноранговые узлы. При нажатии этой кнопки вызывается метод defineImageBinary в файле whiteboard.js.

  6. Откройте файл MyWhiteboard.java и добавьте следующий метод. Этот метод используется для отправки двоичных данных на одноранговые узлы, когда на терминал поступает сообщение с двоичными данными.
    @OnMessage
    public void broadcastSnapshot(ByteBuffer data, Session session) throws IOException {
        System.out.println("broadcastBinary: " + data);
        for (Session peer : peers) {
            if (!peer.equals(session)) {
                peer.getBasicRemote().sendBinary(data);
            }
        }
    }

    Примечание. Потребуется добавить оператор импорта для java.nio.ByteBuffer.

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

  1. Измените метод defineImage в файле whiteboard.js, добавив в него следующий код (выделен полужирным шрифтом).
            drawImageText(json);
        if (document.getElementById("instant").checked) {
            sendText(json);
        }
    }

    Этот код условия проверяет, установлен ли флажок для элемента с этим идентификатором

  2. Откройте файл index.html и измените элемент <table>, добавив в форму флажок.
    <tr>
        <th> </th>
        <td><input type="submit" value="Send Snapshot" onclick="defineImageBinary(); return false;"></td>
        <td><input type="checkbox" id="instant" value="Online" checked="true">Online</td>
        <td> </td>
        <td> </td>
    </tr>
                    

    Если флажок 'Подключено' не установлен, отправка данных не осуществляется, но клиенты по-прежнему могут получать данные от терминала.

Если добавить кнопку 'Отправить снимок' и флажок 'Подключено' и снова запустить приложение, на странице индекса отобразятся новые элементы. Если открыть другой браузер и снять флажок 'Подключено', можно видеть, что при нажатии на полотно сообщение JSON не отправляется на терминал.

снимок приложения в окне браузера

Если нажать кнопку 'Отправить снимок', двоичные данные будут отправлены на терминал, который будет транслировать эти данные на все подключенные клиенты.



См. также

Подробнее об использовании IDE NetBeans для разработки приложений Java EE см. в следующих ресурсах:

Дополнительные сведения об использовании Java EE можно найти в Учебном курсе по Java EE.

To send comments and suggestions, get support, and keep informed on the latest developments on the IDE NetBeans Java EE development features, join the nbj2ee mailing list.

get support for the NetBeans

Support


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo