Начиная с JDeveloper 12.1.3.0 в ADF появилась поддержка Java API for WebSockets.
WebSocket — это протокол связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени.Он позволяет пересылать любые данные, на любой домен, безопасно и почти без лишнего сетевого трафика.
Для демонстрации WebSocket в ADF создадим приложение, в котором будем вводить сообщение в inputtext.
1. Создайте Fusion Middleware приложение
2. В это приложение добавьте проект Web Socket Project
3. После этого, зайдите в свойства созданного проекта и добавьте библиотеку WebSocket.
4. Теперь создайте Java класс для обработки WebSocket событий. Что бы класс был сконфигурирован для работы с WebSocket, пропишите в нем аннотацию ServerEndpoint( например: @ServerEndpoint( value ="/message") )
Аннотация подчеркнётся красным цветом, что бы исправить ошибку, используйте помощник и выберите в нем "Configure Project for Web Socket ..."
Теперь нужно добавить реализацию в созданный класс. В соответствии со спецификацией новый экземпляр класса будет создаваться для каждого соединения WebSocket. И что бы сохранить все активные сессии, мы добавим очередь:
final static Queue<Session> queue = new ConcurrentLinkedQueue<>();
Так же нужно добавить три метода с аннотациями OnOpen(открытие соединения) , OnClose(закрытие соединение), OnError (ошибка) :
Что бы этот класс был доступен в проекте ViewController, зайдите в свойства WebSocet проекта и переименуйте Java EE Web Application Name вместе с Java EE Web Context Root
Создайте Deployment профиль (Jar)
Добавьте этот профиль в зависимости ViewConroller проекта
5. Класс для обработки событий на стороне сервера создан, теперь нужно установить соединение на стороне клиента и отправлять данные на сервер. Для этого создайте js скрипт во ViewController и добавьте следующий код :
Теперь нужно подключить этот скрипт на страницу. Для этого используется тэг af:resource (например: <af:resource type="javascript" source="../resources/js/socket.js" />)
Если запустить приложение, то произойдет подключение к WebSocket. Осталось добавить какую то имплементацию. В моем случае в input text будет вводиться слово,а в output text будет выводиться его инверсия(обратный порядок символов у введенного текста)
На jspx страницу я добавил inputText ( для ввода текста) и outputText. Обратите внимание что у inputText есть clientListener для вызова js функции при изменении значения, а у outputtext есть свойство clientComponent="true", это свойство необходимо для того, что бы возможно было работать с outputText из JS.
Также нужно изменить созданный ранее Java класс, туда нужно добавить метод с аннотацией @OnMessage (обработка отправленных данных с клиента). При помощи session.getBasicRemote().sendText() данные можно отправить обратно клиенту.
Рабочее приложение на github: https://github.com/JealousyM/websocket-adf
Примеры использования WebSocket в ADF(на английском):
http://andrejusb.blogspot.com.by/2015/05/adf-and-two-way-websocket-communication
http://andrejusb.blogspot.com.by/2015/04/websocket-integration-with-adf-for-ppr.html
http://andrejusb.blogspot.com.by/2016/02/oracle-jet-and-websocket-integration.html
WebSocket — это протокол связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени.Он позволяет пересылать любые данные, на любой домен, безопасно и почти без лишнего сетевого трафика.
Для демонстрации WebSocket в ADF создадим приложение, в котором будем вводить сообщение в inputtext.
1. Создайте Fusion Middleware приложение
2. В это приложение добавьте проект Web Socket Project
3. После этого, зайдите в свойства созданного проекта и добавьте библиотеку WebSocket.
4. Теперь создайте Java класс для обработки WebSocket событий. Что бы класс был сконфигурирован для работы с WebSocket, пропишите в нем аннотацию ServerEndpoint( например: @ServerEndpoint( value ="/message") )
Аннотация подчеркнётся красным цветом, что бы исправить ошибку, используйте помощник и выберите в нем "Configure Project for Web Socket ..."
Теперь нужно добавить реализацию в созданный класс. В соответствии со спецификацией новый экземпляр класса будет создаваться для каждого соединения WebSocket. И что бы сохранить все активные сессии, мы добавим очередь:
final static Queue<Session> queue = new ConcurrentLinkedQueue<>();
Так же нужно добавить три метода с аннотациями OnOpen(открытие соединения) , OnClose(закрытие соединение), OnError (ошибка) :
@OnOpen public void open(Session session) { | |
queue.add(session); | |
} | |
@OnClose | |
public void closedConnection(Session session) { | |
queue.remove(session); | |
} | |
@OnError | |
public void error(Session session, Throwable t) { | |
queue.remove(session); | |
t.printStackTrace(); | |
} | |
Что бы этот класс был доступен в проекте ViewController, зайдите в свойства WebSocet проекта и переименуйте Java EE Web Application Name вместе с Java EE Web Context Root
Создайте Deployment профиль (Jar)
Добавьте этот профиль в зависимости ViewConroller проекта
5. Класс для обработки событий на стороне сервера создан, теперь нужно установить соединение на стороне клиента и отправлять данные на сервер. Для этого создайте js скрипт во ViewController и добавьте следующий код :
var wsUri = "ws://"; var socketendpoint = "/WebSocket/message"; //где Websocket название Java EE в //проекте Websocket, а message - название ServerEndpoint | |
var websocket; | |
function getWSUri() { | |
return wsUri + "localhost:7101" + socketendpoint; | |
} | |
//Подключение к WebSocket | |
function connectSocket() { | |
if ('WebSocket' in window){ | |
websocket = new WebSocket(getWSUri()); | |
console.log('socket opened !'); | |
} else { | |
console.log('websocket not supported...!') | |
} | |
} | |
//добавления события, что бы при загрузке страницы выполнялся метод connectSocket | |
window.addEventListener("load", connectSocket, false); |
Теперь нужно подключить этот скрипт на страницу. Для этого используется тэг af:resource (например: <af:resource type="javascript" source="../resources/js/socket.js" />)
Если запустить приложение, то произойдет подключение к WebSocket. Осталось добавить какую то имплементацию. В моем случае в input text будет вводиться слово,а в output text будет выводиться его инверсия(обратный порядок символов у введенного текста)
На jspx страницу я добавил inputText ( для ввода текста) и outputText. Обратите внимание что у inputText есть clientListener для вызова js функции при изменении значения, а у outputtext есть свойство clientComponent="true", это свойство необходимо для того, что бы возможно было работать с outputText из JS.
<af:panelGroupLayout id="pgl2" layout="vertical"> <af:inputText label="Enter text:" id="message"> | |
<af:clientListener method="processInverse" type="valueChange"/> | |
</af:inputText> | |
<af:outputText value="" id="inverseText" clientComponent="true"/> | |
</af:panelGroupLayout> |
Теперь нужно немного изменить скрипт созданный ранее, а именно: изменить метод connectSocket и добавить функции для обработки коллбэков websocket
//Подключение к WebSocket function connectSocket() { | |
if ('WebSocket' in window){ | |
websocket = new WebSocket(getWSUri()); | |
websocket.onmessage = onMessage; | |
websocket.onerror = onError; | |
websocket.onclose = onClose; | |
console.log('socket opened !'); | |
} else { | |
console.log('websocket not supported...!') | |
} | |
} |
//функция для обработки ошибок function onError(evt) { console.log('error :' + evt); | |
} | |
//функция вызывающаяся при закрытии соединения | |
function onClose(evt) { | |
console.log('websocket closed :' + evt.code + ":" + evt.reason); | |
} | |
//функция для обработки полученных данных (в моем случае данные с сервера //просто записываются в outputText) | |
function onMessage(evt) { | |
console.log("on message ->" + event.data) | |
inverseText = AdfPage.PAGE.findComponentByAbsoluteId("inverseText"); | |
inverseText.setValue("Reverse:".concat(event.data)) | |
} | |
//функция вызывающаяся при изменении inputText. Измененное значение при помощи //websocket.send() отправляет данных на сервер | |
function processInverse(actionEvent) { | |
websocket.send(actionEvent.getSource().getValue()) | |
} |
@OnMessage public void processMessage(Session session, String message) { | |
try { | |
session.getBasicRemote().sendText(new StringBuilder(message).reverse().toString()); | |
} catch (IOException e) { | |
System.out.println("IOException:"+e); | |
} | |
} |
Готово.
Рабочее приложение на github: https://github.com/JealousyM/websocket-adf
Примеры использования WebSocket в ADF(на английском):
http://andrejusb.blogspot.com.by/2015/05/adf-and-two-way-websocket-communication
http://andrejusb.blogspot.com.by/2015/04/websocket-integration-with-adf-for-ppr.html
http://andrejusb.blogspot.com.by/2016/02/oracle-jet-and-websocket-integration.html
Комментариев нет:
Отправить комментарий