summaryrefslogtreecommitdiffstats
path: root/documentation/advanced/advanced-push.asciidoc
diff options
context:
space:
mode:
authorIlia Motornyi <elmot@vaadin.com>2015-12-03 14:59:05 +0000
committerVaadin Code Review <review@vaadin.com>2015-12-03 14:59:12 +0000
commit2af72ba9636bec70046394c41744f89ce4572e35 (patch)
treeccb3dc2d2239585f8c3f79eb5f131ff61ca9ce86 /documentation/advanced/advanced-push.asciidoc
parent8aa5fabe89f2967e966a64842a608eceaf80d08f (diff)
downloadvaadin-framework-2af72ba9636bec70046394c41744f89ce4572e35.tar.gz
vaadin-framework-2af72ba9636bec70046394c41744f89ce4572e35.zip
Revert "Merge branch 'documentation'"7.6.0.beta2
This reverts commit f6874bde3d945c8b2d1b5c17ab50e2d0f1f8ff00. Change-Id: I67ee1c30ba3e3bcc3c43a1dd2e73a822791514bf
Diffstat (limited to 'documentation/advanced/advanced-push.asciidoc')
-rw-r--r--documentation/advanced/advanced-push.asciidoc417
1 files changed, 0 insertions, 417 deletions
diff --git a/documentation/advanced/advanced-push.asciidoc b/documentation/advanced/advanced-push.asciidoc
deleted file mode 100644
index df9279c6bb..0000000000
--- a/documentation/advanced/advanced-push.asciidoc
+++ /dev/null
@@ -1,417 +0,0 @@
----
-title: Server Push
-order: 16
-layout: page
----
-
-[[advanced.push]]
-= Server Push
-
-When you need to update a UI from another UI, possibly of another user, or from
-a background thread running in the server, you usually want to have the update
-show immediately, not when the browser happens to make the next server request.
-For this purpose, you can use __server push__ that sends the data to the browser
-immediately. Push is based on a client-server connection, usually a WebSocket
-connection, that the client establishes and the server can then use to send
-updates to the client.
-
-The server-client communication is done by default with a WebSocket connection
-if the browser and the server support it. If not, Vaadin will fall back to a
-method supported by the browser. Vaadin Push uses a custom build of the
-link:https://github.com/Atmosphere/atmosphere[Atmosphere framework] for
-client-server communication.
-
-[[advanced.push.installation]]
-== Installing the Push Support
-
-The server push support in Vaadin requires the separate Vaadin Push library. It
-is included in the installation package as [filename]#vaadin-push.jar#.
-
-[[advanced.push.installation.ivy]]
-=== Retrieving with Ivy
-
-With Ivy, you can get it with the following declaration in the
-[filename]#ivy.xml#:
-
-
-[source, xml]
-----
-<dependency org="com.vaadin" name="vaadin-push"
- rev="&vaadin.version;" conf="default->default"/>
-----
-
-In some servers, you may need to exlude a [literal]#++sl4j++# dependency as
-follows:
-
-
-[source, xml]
-----
-<dependency org="com.vaadin" name="vaadin-push"
- rev="&vaadin.version;" conf="default->default">
- <exclude org="org.slf4j" name="slf4j-api"/>
-</dependency>
-----
-
-Pay note that the Atmosphere library is a bundle, so if you retrieve the
-libraries with Ant, for example, you need to retrieve
-[literal]#++type="jar,bundle"++#.
-
-
-[[advanced.push.installation.maven]]
-=== Retrieving with Maven
-
-In Maven, you can get the push library with the following dependency in the POM:
-
-
-[source, xml]
-----
-<dependency>
- <groupId>com.vaadin</groupId>
- <artifactId>vaadin-push</artifactId>
- <version>${vaadin.version}</version>
-</dependency>
-----
-
-
-
-[[advanced.push.enabling]]
-== Enabling Push for a UI
-
-To enable server push, you need to define the push mode either in the deployment
-descriptor or with the [classname]#@Push# annotation for the UI.
-
-[[advanced.push.enabling.pushmode]]
-=== Push Modes
-
-You can use server push in two modes: [literal]#++automatic++# and
-[literal]#++manual++#. The automatic mode pushes changes to the browser
-automatically after access() finishes. With the manual mode, you can do the push
-explicitly with [methodname]#push()#, which allows more flexibility.
-
-
-[[advanced.push.enabling.pushmode]]
-=== The [classname]#@Push# annotation
-
-You can enable server push for a UI with the [classname]#@Push# annotation as
-follows. It defaults to automatic mode ( [parameter]#PushMode.AUTOMATIC#).
-
-
-[source, java]
-----
-@Push
-public class PushyUI extends UI {
-----
-
-To enable manual mode, you need to give the [parameter]#PushMode.MANUAL#
-parameter as follows:
-
-
-[source, java]
-----
-@Push(PushMode.MANUAL)
-public class PushyUI extends UI {
-----
-
-
-[[advanced.push.enabling.servlet]]
-=== Servlet Configuration
-
-You can enable the server push and define the push mode also in the servlet
-configuration with the [parameter]#pushmode# parameter for the servlet in the
-[filename]#web.xml# deployment descriptor. If you use a Servlet 3.0 compatible
-server, you also want to enable asynchronous processing with the
-[literal]#++async-supported++# parameter. Note the use of Servlet 3.0 schema in
-the deployment descriptor.
-
-
-[subs="normal"]
-----
-&lt;?xml version="1.0" encoding="UTF-8"?&gt;
-&lt;web-app
- id="WebApp_ID" version="**3.0**"
- xmlns="**http://java.sun.com/xml/ns/javaee**"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="**http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd**"&gt;
- &lt;servlet&gt;
- &lt;servlet-name&gt;Pushy UI&lt;/servlet-name&gt;
- &lt;servlet-class&gt;
- com.vaadin.server.VaadinServlet&lt;/servlet-class&gt;
-
- &lt;init-param&gt;
- &lt;param-name&gt;UI&lt;/param-name&gt;
- &lt;param-value&gt;**com.example.my.PushyUI**&lt;/param-value&gt;
- &lt;/init-param&gt;
-
- &lt;!-- Enable server push --&gt;
- &lt;init-param&gt;
- &lt;param-name&gt;pushmode&lt;/param-name&gt;
- &lt;param-value&gt;**automatic**&lt;/param-value&gt;
- &lt;/init-param&gt;
- &lt;async-supported&gt;**true**&lt;/async-supported&gt;
- &lt;/servlet&gt;
-&lt;/web-app&gt;
-----
-
-[[advanced.push.running]]
-== Accessing UI from Another Thread
-
-Making changes to a [classname]#UI# object from another thread and pushing them
-to the browser requires locking the user session when accessing the UI.
-Otherwise, the UI update done from another thread could conflict with a regular
-event-driven update and cause either data corruption or deadlocks. Because of
-this, you may only access an UI using the [methodname]#access()# method, which
-locks the session to prevent conflicts. It takes a [interfacename]#Runnable#
-which it executes as its parameter.
-
-For example:
-
-
-[source, java]
-----
-ui.access(new Runnable() {
- @Override
- public void run() {
- series.add(new DataSeriesItem(x, y));
- }
-});
-----
-
-In Java 8, where a parameterless lambda expression creates a runnable, you could
-simply write:
-
-
-[source, java]
-----
-ui.access(() ->
- series.add(new DataSeriesItem(x, y)));
-----
-
-If the push mode is [literal]#++manual++#, you need to push the pending UI
-changes to the browser explicitly with the [methodname]#push()# method.
-
-
-[source, java]
-----
-ui.access(new Runnable() {
- @Override
- public void run() {
- series.add(new DataSeriesItem(x, y));
- ui.push();
- }
-});
-----
-
-Below is a complete example of a case where we make UI changes from another
-thread.
-
-
-[source, java]
-----
-public class PushyUI extends UI {
- Chart chart = new Chart(ChartType.AREASPLINE);
- DataSeries series = new DataSeries();
-
- @Override
- protected void init(VaadinRequest request) {
- chart.setSizeFull();
- setContent(chart);
-
- // Prepare the data display
- Configuration conf = chart.getConfiguration();
- conf.setTitle("Hot New Data");
- conf.setSeries(series);
-
- // Start the data feed thread
- new FeederThread().start();
- }
-
- class FeederThread extends Thread {
- int count = 0;
-
- @Override
- public void run() {
- try {
- // Update the data for a while
- while (count < 100) {
- Thread.sleep(1000);
-
- access(new Runnable() {
- @Override
- public void run() {
- double y = Math.random();
- series.add(
- new DataSeriesItem(count++, y),
- true, count > 10);
- }
- });
- }
-
- // Inform that we have stopped running
- access(new Runnable() {
- @Override
- public void run() {
- setContent(new Label("Done!"));
- }
- });
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
-}
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.push.simple[on-line example, window="_blank"].
-
-When sharing data between UIs or user sessions, you need to consider the
-message-passing mechanism more carefully, as explained next.
-
-
-[[advanced.push.pusharound]]
-== Broadcasting to Other Users
-
-Broadcasting messages to be pushed to UIs in other user sessions requires having
-some sort of message-passing mechanism that sends the messages to all UIs that
-register as recipients. As processing server requests for different UIs is done
-concurrently in different threads of the application server, locking the threads
-properly is very important to avoid deadlock situations.
-
-[[advanced.push.pusharound.broadcaster]]
-=== The Broadcaster
-
-The standard pattern for sending messages to other users is to use a
-__broadcaster__ singleton that registers the UIs and broadcasts messages to them
-safely. To avoid deadlocks, it is recommended that the messages should be sent
-through a message queue in a separate thread. Using a Java
-[classname]#ExecutorService# running in a single thread is usually the easiest
-and safest way.
-
-
-[source, java]
-----
-public class Broadcaster implements Serializable {
- static ExecutorService executorService =
- Executors.newSingleThreadExecutor();
-
- public interface BroadcastListener {
- void receiveBroadcast(String message);
- }
-
- private static LinkedList<BroadcastListener> listeners =
- new LinkedList<BroadcastListener>();
-
- public static synchronized void register(
- BroadcastListener listener) {
- listeners.add(listener);
- }
-
- public static synchronized void unregister(
- BroadcastListener listener) {
- listeners.remove(listener);
- }
-
- public static synchronized void broadcast(
- final String message) {
- for (final BroadcastListener listener: listeners)
- executorService.execute(new Runnable() {
- @Override
- public void run() {
- listener.receiveBroadcast(message);
- }
- });
- }
-}
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.push.pusharound[on-line example, window="_blank"].
-
-In Java 8, you could use lambda expressions for the listeners instead of the
-interface, and a parameterless expression to create the runnable:
-
-
-[source, java]
-----
-for (final Consumer<String> listener: listeners)
- executorService.execute(() ->
- listener.accept(message));
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.push.pusharound[on-line example, window="_blank"].
-
-
-[[advanced.push.pusharound.receiving]]
-=== Receiving Broadcasts
-
-The receivers need to implement the receiver interface and register to the
-broadcaster to receive the broadcasts. A listener should be unregistered when
-the UI expires. When updating the UI in a receiver, it should be done safely as
-described earlier, by executing the update through the [methodname]#access()#
-method of the UI.
-
-
-[source, java]
-----
-@Push
-public class PushAroundUI extends UI
- implements Broadcaster.BroadcastListener {
-
- VerticalLayout messages = new VerticalLayout();
-
- @Override
- protected void init(VaadinRequest request) {
- ... build the UI ...
-
- // Register to receive broadcasts
- Broadcaster.register(this);
- }
-
- // Must also unregister when the UI expires
- @Override
- public void detach() {
- Broadcaster.unregister(this);
- super.detach();
- }
-
- @Override
- public void receiveBroadcast(final String message) {
- // Must lock the session to execute logic safely
- access(new Runnable() {
- @Override
- public void run() {
- // Show it somehow
- messages.addComponent(new Label(message));
- }
- });
- }
-}
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.push.pusharound[on-line example, window="_blank"].
-
-
-[[advanced.push.pusharound.sending]]
-=== Sending Broadcasts
-
-To send broadcasts with a broadcaster singleton, such as the one described
-above, you would only need to call the [methodname]#broadcast()# method as
-follows.
-
-
-[source, java]
-----
-final TextField input = new TextField();
-sendBar.addComponent(input);
-
-Button send = new Button("Send");
-send.addClickListener(new ClickListener() {
- @Override
- public void buttonClick(ClickEvent event) {
- // Broadcast the message
- Broadcaster.broadcast(input.getValue());
-
- input.setValue("");
- }
-});
-----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#advanced.push.pusharound[on-line example, window="_blank"].
-
-
-
-
-