]> source.dussan.org Git - vaadin-framework.git/commitdiff
Migrate documentation files and change typo pr9959/r1
authorErik Lumme <erik@vaadin.com>
Mon, 11 Sep 2017 11:02:42 +0000 (14:02 +0300)
committerErik Lumme <erik@vaadin.com>
Mon, 11 Sep 2017 11:02:42 +0000 (14:02 +0300)
documentation/articles/AccessingWebPageAndBrowserInformation.asciidoc [new file with mode: 0644]
documentation/articles/ConfiguringPushForYourEnviroment.asciidoc [deleted file]
documentation/articles/ConfiguringPushForYourEnvironment.asciidoc [new file with mode: 0644]
documentation/articles/GeneratingDynamicResourcesBasedOnURIOrParameters.asciidoc [new file with mode: 0644]
documentation/articles/UsingURIFragments.asciidoc [new file with mode: 0644]
documentation/articles/contents.asciidoc

diff --git a/documentation/articles/AccessingWebPageAndBrowserInformation.asciidoc b/documentation/articles/AccessingWebPageAndBrowserInformation.asciidoc
new file mode 100644 (file)
index 0000000..2aea7b8
--- /dev/null
@@ -0,0 +1,50 @@
+[[accessing-web-page-and-browser-information]]
+Accessing web page and browser information
+------------------------------------------
+
+Vaadin 7 includes a new *Page* class offering access to various
+client-side information and events concerning the web page and browser
+window in which the Vaadin UI resides. The Page instance corresponding
+to a given UI is accessed via the `getPage()` method of the UI or using
+a static method `Page.getCurrent()`.
+
+You can access the browser window size and add size change listeners:
+
+[source,java]
+....
+Page page = someUI.getPage();
+page.addBrowserWindowResizeListener(new BrowserWindowResizeListener() {
+  public void browserWindowResized(BrowserWindowResizeEvent event) {
+    Notification.show("Window width=" + event.getWidth() + ", height=" + event.getHeight());
+  }
+});
+....
+
+You can access the optional fragment part of the location URI and add
+fragment change listeners:
+
+[source,java]
+....
+page.setUriFragment(page.getUriFragment() + "foo");
+page.addUriFragmentChangedListener(new UriFragmentChangedListener() {
+  public void uriFragmentChanged(UriFragmentChangedEvent event) {
+    Notification.show("Fragment=" + event.getUriFragment());
+  }
+});
+....
+
+You can access client browser details:
+
+[source,java]
+....
+Notification.show("IP" + browser.getAddress() +
+                "User-Agent:" + browser.getBrowserApplication() +
+                "Linux: " + browser.isLinux());
+....
+
+https://demo.vaadin.com/sampler/#foundation/advanced/browser-information[Live
+Demo]
+
+Note: If you are using a reverse proxy, you must get the value
+`X-Forwarded-For` from request headers. You cannot get a browser name,
+but you can check which browser are using.
diff --git a/documentation/articles/ConfiguringPushForYourEnviroment.asciidoc b/documentation/articles/ConfiguringPushForYourEnviroment.asciidoc
deleted file mode 100644 (file)
index dd837e5..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-[[configuring-push-for-your-environment]]
-Configuring Push For Your Enviroment
-------------------------------------
-
-Server push and especially websockets are emerging technologies and not
-all servers and browsers handle them correctly (or even close to
-correctly). Here are gathered a few known issues and ways to work around
-them:
-
-*Rule of thumb: Use the latest version of your server and the latest
-Vaadin version. Vaadin 7.6 has a completely rewritten logic for dealing
-with buffering proxies and unreliabilities in the connection to the
-server.*
-
-[[portals]]
-Portals
-~~~~~~~
-
-Push is not supported in portals.
-See https://dev.vaadin.com/ticket/11493 for more information.
-
-[[streaming]]
-Streaming
-~~~~~~~~~
-
-*Avoid streaming and use long-polling instead*. Streaming and
-long-polling works similarly on top of normal HTTP requests but
-streaming uses the same HTTP response for multiple messages whereas
-long-polling only writes on message per HTTP response. Especially
-proxies can cause problems with streaming as they might deliver only
-part of the message and buffer the rest.
-
-[[tomcat-6-streaming]]
-Tomcat 6 + Streaming
-~~~~~~~~~~~~~~~~~~~~
-
-For Tomcat 6, falling back to streaming always results in an error message such as
-[source]
-....
-Failed using comet support: org.atmosphere.container.TomcatCometSupport, error: Tomcat failed to detect this is a Comet application because context.xml is missing or the Http11NioProtocol Connector is not enabled.If that's not the case, you can also remove META-INF/context.xml and WEB-INF/lib/atmosphere-compat-tomcat.jar Is the Nio or Apr Connector enabled?WARNING: Using org.atmosphere.container.BlockingIOCometSupport`
-....
-
-Atmosphere is expecting the Servlet to implement Tomcat's proprietary interface https://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/CometProcessor.html[CometProcessor]. (See https://github.com/Atmosphere/atmosphere/blob/atmosphere-project-1.0.14/modules/cpr/src/main/java/org/atmosphere/cpr/AtmosphereServlet.java[AtmosphereServlet])
-
-Vaadin's default servlet does not implement this interface.
-
-When fallback to native Comet fails, Atmosphere uses
-`BlockingIOCometSupport`, which seems to work with some applications and
-not with others. If it does not work for your application, you may want
-to try Tomcat 7 with a Servlet 3.0 application.
-
-[[tomcat-7-streaming]]
-Tomcat 7 + Streaming
-~~~~~~~~~~~~~~~~~~~~
-
-For Tomcat 7, if your application is a Servlet 3.0 application, set the
-property `org.atmosphere.useWebSocketAndServlet3=true` and make sure
-your Servlet and your filters in Web.xml have
-`<async-supported>true</async-supported>` or the equivalent annotation.
-
-For Servlet < 3.0, see "Tomcat6 + Streaming" above.
-
-[[tomcat-7-websockets]]
-Tomcat 7 + Websockets
-~~~~~~~~~~~~~~~~~~~~~
-
-Tomcat 7 is unable to share the HTTP session between HTTP request and
-websockets request. Because of this a FakeHttpSession (a copy of the
-real session) is used for websockets. This has certain implications such
-as that it is impossible to invalidate the session from a websockets
-enabled application. Tomcat 8 does not have this problem.
-
-The Websockets implementation in the 7.0.2x series is rather immature,
-so all kinds of issues may occur. 
-
-If you use Tomcat 7, upgrade to the latest version!
-
-*It is recommended to upgrade to the latest Tomcat 8 (requires Vaadin
-7.2+) if you want to use websockets.*
-
-[[tomcat-8-websockets]]
-Tomcat 8 + Websockets
-~~~~~~~~~~~~~~~~~~~~~
-
-....
-java.lang.ClassNotFoundException: org.eclipse.jetty.websocket.WebSocketFactory$Acceptor
-....
-
-This implies you have Jetty deployed on the classpath somewhere.
-Atmosphere gets confused and tries to use its Websocket implementation
-instead of Tomcat's. One common reason for this is that you have
-accidentally deployed vaadin-client-compiler, which has Jetty as a
-dependency (needed by SuperDevMode for instance.)
-
-[[glassfish-234-streaming]]
-Glassfish 2/3/4 + Streaming
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Glassfish 2/3/4 requires the "comet" option to be enabled for streaming
-to work.
-
-For Glassfish 2, set
-`(Configurations -> HTTP service -> HTTP listeners -> http-listener-1 -> Add Property -> "cometSupport"="true")`
-or use
-`asadmin set server.http-service.http-listener.http-listener-1.property.cometSupport=true`
-
-For Glassfish 3/4, set
-`(Configurations -> server-config -> Network Config -> Protocols -> http-listener-1 -> HTTP -> Comet Support)`
-or use
-`asadmin set server-config.network-config.protocols.protocol.http-listener-1.http.comet-support-enabled="true"`
-
-[[glassfish-3-websockets]]
-Glassfish 3 + Websockets
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-As a rule of thumb, don't do this.
-
-The Grizzly version shipped with Glassfish 3.1.2.2 contains a
-https://java.net/jira/browse/GRIZZLY-1289[fatal bug] which prevents
-Vaadin from working. Replace *glassfish/modules/grizzly-websockets.jar*
-with
-https://java.net/jira/secure/attachment/50681/grizzly-websockets-1.9.50-fix.jar
-to get websockets working (with Vaadin 7.3). *This version is actually
-also broken in many ways, so you may or may not get it to work. If you
-want websockets, you should upgrade to Glassfish 4.*
-
-Glassfish 3 requires the websockets option to be enabled for websockets
-to work
-`(Configurations -> server-config -> Network Config -> Protocols -> http-listener-1 -> HTTP -> Websockets Support)`
-or
-`asadmin set server-config.network-config.protocols.protocol.http-listener-1.http.websockets-support-enabled="true"`.
-
-[[glassfish-4-websockets]]
-Glassfish 4 + Websockets
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Glassfish 4 + websockets require Vaadin 7.2+. *If you are using
-Glassfish 4.0, upgrade to Glassfish 4.1 to avoid problems*
-
-[[wildfly-8-websockets]]
-Wildfly 8 + Websockets
-~~~~~~~~~~~~~~~~~~~~~~
-
-Wildfly requires all websocket endpoints to be deployed during web
-application initialization and refuses to deploy them later. If you are
-using multiple push enabled Vaadin servlets you should mark them as
-load-on-startup=true to avoid issues. (Vaadin 7.2-7.4). Vaadin 7.5 fixes
-this by initializing websockets during context deployment so
-load-on-startup is not needed.
-
-[[weblogic-12-websockets]]
-Weblogic 12 + Websockets
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Use WebLogic 12.1.3 or newer with Java 8 and Vaadin 7.5+.
-
-If you see "java.lang.IllegalStateException:
-javax.websocket.server.ServerContainer is null. Make sure you are using
-1.8+ and your server has websocket support enabled" you are probably
-running with Java 7 or older.
-
-WebLogic 12 specifies a timeout of 30s by default for websocket
-connections
-(https://docs.oracle.com/middleware/1212/wls/WLPRG/websockets.htm#WLPRG811).
-To avoid constant reconnects, you can set the init
-parameter `weblogic.websocket.tyrus.session-max-idle-timeout` to either
--1 (no timeout in use) or a higher value than 30000 (value is in ms).
-
-[[jboss-eap-6.4-and-websockets]]
-JBoss EAP 6.4  and Websockets
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-JBoss EAP 6.4 includes support for websockets but they are not enabled
-by default. To make websockets work you need to
-
-1. Change JBoss to use the NIO connector
-+
-This can be done by running
-+
-`$ bin/jboss-cli.sh --connect`
-+
-and the following commands
-+
-....
-batch
-/subsystem=web/connector=http/:write-attribute(name=protocol,value=org.apache.coyote.http11.Http11NioProtocol)
-run-batch
-:reload
-....
-
-2. Add a *WEB-INF/jboss-web.xml* to you war file with the following
-contents to enable websockets
-
-[source,xml]
-....
-<jboss-web version="7.2" xmlns="http://www.jboss.com/xml/ns/javaee"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee schema/jboss-web_7_2.xsd">
-    <enable-websockets>true</enable-websockets>
-</jboss-web>
-....
-
-[[liberty-profileand-websockets]]
-Liberty profile and Websockets
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Use Liberty beta 2015.9.0.0 or later and Vaadin 7.6+.
-
-[[buffering-proxies-and-long-polling]]
-Buffering proxies and long polling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Use Vaadin 7.6+ to deal with buffering proxies. Also see "Duplicate
-resource xyz-abc-def-ghi-jkl" below
-
-[[kaspersky-anti-virus-long-polling]]
-Kaspersky anti virus + long polling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Use Vaadin 7.6+ to avoid problems with long polling.
-
-[[chrome-sayserr_incomplete_chunked_encoding]]
-Chrome says ERR_INCOMPLETE_CHUNKED_ENCODING
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is completely normal and means that the (long-polling) push
-connection was aborted by a third party. This typically happens when
-there is a proxy between the browser and the server and the proxy has a
-configured timeout and cuts the connection when the timeout is reached.
-The browser should reconnect to the server normally after this happens.
-
-Server logs contain
-
-....
-Duplicate resource xyz-abc-def-ghi-jkl. Could be
-caused by a dead connection not detected by your server. Replacing the
-old one with the fresh one"
-....
-
-This indicates that first, the browser connected to the server and used
-the given identifier for the push connection. Everything went as
-expected. Later on, a browser (probably the same one) connected again using the
-same identifier but according to the server, the old browser connection
-should still be active. The server closes the old connection and logs
-the warning.
-
-[[why-does-this-happen]]
-Why does this happen?
-^^^^^^^^^^^^^^^^^^^^^
-
-Typically there was a proxy between the browser and the server, and the
-proxy was configured to kill open connections after a certain inactivity
-timeout on the connection (no data is sent before the server issues a
-push command). Because of how TCP/IP works, the server has no idea that
-the connection has been killed and continues to think that the old
-client is connected and all is well.
-
-[[what-can-you-do-to-avoid-this]]
-What can you do to avoid this?
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You have a couple of options:
-
-1.  If you are in control of the proxy, configure it not to timeout/kill
-push connections (connections to the /PUSH url)
-2.  If you know what the proxy timeout is, configure a slightly shorter
-timeout for push in the Vaadin application so that the server terminates
-the idle connection and is aware of the termination before the proxy can
-kill the connection. Use the `pushLongPollingSuspendTimeout` servlet
-parameter for this (defined in milliseconds) (Vaadin 7.6+)
-
-If you do not configure the proxy so that the server knows when the
-connection is killed, you also have a small chance of losing pushed
-data. If it so happens that the server does a push right after the
-connection was killed, it will not realize that it pushed data into a
-closed connection (because of how sockets work and especially how they
-work in Java). Disabling the timeout or setting the timeout on the
-server also resolves this potential issue.
diff --git a/documentation/articles/ConfiguringPushForYourEnvironment.asciidoc b/documentation/articles/ConfiguringPushForYourEnvironment.asciidoc
new file mode 100644 (file)
index 0000000..ee9c363
--- /dev/null
@@ -0,0 +1,278 @@
+[[configuring-push-for-your-environment]]
+Configuring push for your environment
+-------------------------------------
+
+Server push and especially websockets are emerging technologies and not
+all servers and browsers handle them correctly (or even close to
+correctly). Here are gathered a few known issues and ways to work around
+them:
+
+*Rule of thumb: Use the latest version of your server and the latest
+Vaadin version. Vaadin 7.6 has a completely rewritten logic for dealing
+with buffering proxies and unreliabilities in the connection to the
+server.*
+
+[[portals]]
+Portals
+~~~~~~~
+
+Push is not supported in portals.
+See https://dev.vaadin.com/ticket/11493 for more information.
+
+[[streaming]]
+Streaming
+~~~~~~~~~
+
+*Avoid streaming and use long-polling instead*. Streaming and
+long-polling works similarly on top of normal HTTP requests but
+streaming uses the same HTTP response for multiple messages whereas
+long-polling only writes on message per HTTP response. Especially
+proxies can cause problems with streaming as they might deliver only
+part of the message and buffer the rest.
+
+[[tomcat-6-streaming]]
+Tomcat 6 + Streaming
+~~~~~~~~~~~~~~~~~~~~
+
+For Tomcat 6, falling back to streaming always results in an error message such as
+[source]
+....
+Failed using comet support: org.atmosphere.container.TomcatCometSupport, error: Tomcat failed to detect this is a Comet application because context.xml is missing or the Http11NioProtocol Connector is not enabled.If that's not the case, you can also remove META-INF/context.xml and WEB-INF/lib/atmosphere-compat-tomcat.jar Is the Nio or Apr Connector enabled?WARNING: Using org.atmosphere.container.BlockingIOCometSupport
+....
+
+Atmosphere is expecting the Servlet to implement Tomcat's proprietary interface https://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/CometProcessor.html[CometProcessor]. (See https://github.com/Atmosphere/atmosphere/blob/atmosphere-project-1.0.14/modules/cpr/src/main/java/org/atmosphere/cpr/AtmosphereServlet.java[AtmosphereServlet])
+
+Vaadin's default servlet does not implement this interface.
+
+When fallback to native Comet fails, Atmosphere uses
+`BlockingIOCometSupport`, which seems to work with some applications and
+not with others. If it does not work for your application, you may want
+to try Tomcat 7 with a Servlet 3.0 application.
+
+[[tomcat-7-streaming]]
+Tomcat 7 + Streaming
+~~~~~~~~~~~~~~~~~~~~
+
+For Tomcat 7, if your application is a Servlet 3.0 application, set the
+property `org.atmosphere.useWebSocketAndServlet3=true` and make sure
+your Servlet and your filters in Web.xml have
+`<async-supported>true</async-supported>` or the equivalent annotation.
+
+For Servlet < 3.0, see "Tomcat6 + Streaming" above.
+
+[[tomcat-7-websockets]]
+Tomcat 7 + Websockets
+~~~~~~~~~~~~~~~~~~~~~
+
+Tomcat 7 is unable to share the HTTP session between HTTP request and
+websockets request. Because of this a FakeHttpSession (a copy of the
+real session) is used for websockets. This has certain implications such
+as that it is impossible to invalidate the session from a websockets
+enabled application. Tomcat 8 does not have this problem.
+
+The Websockets implementation in the 7.0.2x series is rather immature,
+so all kinds of issues may occur. 
+
+If you use Tomcat 7, upgrade to the latest version!
+
+*It is recommended to upgrade to the latest Tomcat 8 (requires Vaadin
+7.2+) if you want to use websockets.*
+
+[[tomcat-8-websockets]]
+Tomcat 8 + Websockets
+~~~~~~~~~~~~~~~~~~~~~
+
+....
+java.lang.ClassNotFoundException: org.eclipse.jetty.websocket.WebSocketFactory$Acceptor
+....
+
+This implies you have Jetty deployed on the classpath somewhere.
+Atmosphere gets confused and tries to use its Websocket implementation
+instead of Tomcat's. One common reason for this is that you have
+accidentally deployed vaadin-client-compiler, which has Jetty as a
+dependency (needed by SuperDevMode for instance.)
+
+[[glassfish-234-streaming]]
+Glassfish 2/3/4 + Streaming
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Glassfish 2/3/4 requires the "comet" option to be enabled for streaming
+to work.
+
+For Glassfish 2, set
+`(Configurations -> HTTP service -> HTTP listeners -> http-listener-1 -> Add Property -> "cometSupport"="true")`
+or use
+`asadmin set server.http-service.http-listener.http-listener-1.property.cometSupport=true`
+
+For Glassfish 3/4, set
+`(Configurations -> server-config -> Network Config -> Protocols -> http-listener-1 -> HTTP -> Comet Support)`
+or use
+`asadmin set server-config.network-config.protocols.protocol.http-listener-1.http.comet-support-enabled="true"`
+
+[[glassfish-3-websockets]]
+Glassfish 3 + Websockets
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+As a rule of thumb, don't do this.
+
+The Grizzly version shipped with Glassfish 3.1.2.2 contains a
+https://github.com/javaee/grizzly/issues/1289[fatal bug] which prevents
+Vaadin from working. Replace *glassfish/modules/grizzly-websockets.jar*
+with
+http://central.maven.org/maven2/com/sun/grizzly/grizzly-websockets/1.9.56/grizzly-websockets-1.9.56.jar
+to get websockets working (with Vaadin 7.3). *This version is actually
+also broken in many ways, so you may or may not get it to work. If you
+want websockets, you should upgrade to Glassfish 4.*
+
+Glassfish 3 requires the websockets option to be enabled for websockets
+to work
+`(Configurations -> server-config -> Network Config -> Protocols -> http-listener-1 -> HTTP -> Websockets Support)`
+or
+`asadmin set server-config.network-config.protocols.protocol.http-listener-1.http.websockets-support-enabled="true"`.
+
+[[glassfish-4-websockets]]
+Glassfish 4 + Websockets
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Glassfish 4 + websockets require Vaadin 7.2+. *If you are using
+Glassfish 4.0, upgrade to Glassfish 4.1 to avoid problems*
+
+[[wildfly-8-websockets]]
+Wildfly 8 + Websockets
+~~~~~~~~~~~~~~~~~~~~~~
+
+Wildfly requires all websocket endpoints to be deployed during web
+application initialization and refuses to deploy them later. If you are
+using multiple push enabled Vaadin servlets you should mark them as
+load-on-startup=true to avoid issues. (Vaadin 7.2-7.4). Vaadin 7.5 fixes
+this by initializing websockets during context deployment so
+load-on-startup is not needed.
+
+[[weblogic-12-websockets]]
+Weblogic 12 + Websockets
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use WebLogic 12.1.3 or newer with Java 8 and Vaadin 7.5+.
+
+If you see "java.lang.IllegalStateException:
+javax.websocket.server.ServerContainer is null. Make sure you are using
+1.8+ and your server has websocket support enabled" you are probably
+running with Java 7 or older.
+
+WebLogic 12 specifies a timeout of 30s by default for websocket
+connections
+(https://docs.oracle.com/middleware/1212/wls/WLPRG/websockets.htm#WLPRG811).
+To avoid constant reconnects, you can set the init
+parameter `weblogic.websocket.tyrus.session-max-idle-timeout` to either
+-1 (no timeout in use) or a higher value than 30000 (value is in ms).
+
+[[jboss-eap-6.4-and-websockets]]
+JBoss EAP 6.4  and Websockets
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+JBoss EAP 6.4 includes support for websockets but they are not enabled
+by default. To make websockets work you need to
+
+1. Change JBoss to use the NIO connector
++
+This can be done by running
++
+`$ bin/jboss-cli.sh --connect`
++
+and the following commands
++
+....
+batch
+/subsystem=web/connector=http/:write-attribute(name=protocol,value=org.apache.coyote.http11.Http11NioProtocol)
+run-batch
+:reload
+....
+
+2. Add a *WEB-INF/jboss-web.xml* to you war file with the following
+contents to enable websockets
+
+[source,xml]
+....
+<jboss-web version="7.2" xmlns="http://www.jboss.com/xml/ns/javaee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee schema/jboss-web_7_2.xsd">
+    <enable-websockets>true</enable-websockets>
+</jboss-web>
+....
+
+[[liberty-profileand-websockets]]
+Liberty profile and Websockets
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use Liberty beta 2015.9.0.0 or later and Vaadin 7.6+.
+
+[[buffering-proxies-and-long-polling]]
+Buffering proxies and long polling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use Vaadin 7.6+ to deal with buffering proxies. Also see "Duplicate
+resource xyz-abc-def-ghi-jkl" below
+
+[[kaspersky-anti-virus-long-polling]]
+Kaspersky anti virus + long polling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Use Vaadin 7.6+ to avoid problems with long polling.
+
+[[chrome-sayserr_incomplete_chunked_encoding]]
+Chrome says ERR_INCOMPLETE_CHUNKED_ENCODING
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is completely normal and means that the (long-polling) push
+connection was aborted by a third party. This typically happens when
+there is a proxy between the browser and the server and the proxy has a
+configured timeout and cuts the connection when the timeout is reached.
+The browser should reconnect to the server normally after this happens.
+
+Server logs contain
+
+....
+Duplicate resource xyz-abc-def-ghi-jkl. Could be
+caused by a dead connection not detected by your server. Replacing the
+old one with the fresh one"
+....
+
+This indicates that first, the browser connected to the server and used
+the given identifier for the push connection. Everything went as
+expected. Later on, a browser (probably the same one) connected again using the
+same identifier but according to the server, the old browser connection
+should still be active. The server closes the old connection and logs
+the warning.
+
+[[why-does-this-happen]]
+Why does this happen?
+^^^^^^^^^^^^^^^^^^^^^
+
+Typically there was a proxy between the browser and the server, and the
+proxy was configured to kill open connections after a certain inactivity
+timeout on the connection (no data is sent before the server issues a
+push command). Because of how TCP/IP works, the server has no idea that
+the connection has been killed and continues to think that the old
+client is connected and all is well.
+
+[[what-can-you-do-to-avoid-this]]
+What can you do to avoid this?
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You have a couple of options:
+
+1.  If you are in control of the proxy, configure it not to timeout/kill
+push connections (connections to the /PUSH url)
+2.  If you know what the proxy timeout is, configure a slightly shorter
+timeout for push in the Vaadin application so that the server terminates
+the idle connection and is aware of the termination before the proxy can
+kill the connection. Use the `pushLongPollingSuspendTimeout` servlet
+parameter for this (defined in milliseconds) (Vaadin 7.6+)
+
+If you do not configure the proxy so that the server knows when the
+connection is killed, you also have a small chance of losing pushed
+data. If it so happens that the server does a push right after the
+connection was killed, it will not realize that it pushed data into a
+closed connection (because of how sockets work and especially how they
+work in Java). Disabling the timeout or setting the timeout on the
+server also resolves this potential issue.
diff --git a/documentation/articles/GeneratingDynamicResourcesBasedOnURIOrParameters.asciidoc b/documentation/articles/GeneratingDynamicResourcesBasedOnURIOrParameters.asciidoc
new file mode 100644 (file)
index 0000000..9cfc756
--- /dev/null
@@ -0,0 +1,61 @@
+[[generating-dynamic-resources-based-on-uri-or-parameters]]
+Generating dynamic resources based on URI or parameters
+-------------------------------------------------------
+
+You can dynamically generate responses based on e.g. query parameters by
+creating your own `RequestHandler` and registering it with the session.
+
+In this way, you can for instance create an image that draws a text,
+given as a parameter to the image. This has been done in the example
+below:
+
+[source,java]
+....
+public class DynamicImageUI extends UI {
+  public static final String IMAGE_URL = "myimage.png";
+
+  private final RequestHandler requestHandler = new RequestHandler() {
+    @Override
+    public boolean handleRequest(VaadinSession session,
+          VaadinRequest request, VaadinResponse response)
+          throws IOException {
+      if (("/" + IMAGE_URL).equals(request.getPathInfo())) {
+        // Create an image, draw the "text" parameter to it and output
+        // it to the browser.
+        String text = request.getParameter("text");
+        BufferedImage bi = new BufferedImage(100, 30,
+                BufferedImage.TYPE_3BYTE_BGR);
+        bi.getGraphics().drawChars(text.toCharArray(), 0,
+                text.length(), 10, 20);
+        response.setContentType("image/png");
+        ImageIO.write(bi, "png", response.getOutputStream());
+
+        return true;
+      }
+      // If the URL did not match our image URL, let the other request
+      // handlers handle it
+      return false;
+    }
+  };
+
+  @Override
+  public void init(VaadinRequest request) {
+    Resource resource = new ExternalResource(IMAGE_URL + "?text=Hello!");
+
+    getSession().addRequestHandler(requestHandler);
+
+    // Add an image using the resource
+    Image image = new Image("A dynamically generated image", resource);
+
+    setContent(image);
+  }
+
+  @Override
+  public void detach() {
+    super.detach();
+
+    // Clean up
+    getSession().removeRequestHandler(requestHandler);
+  }
+}
+....
diff --git a/documentation/articles/UsingURIFragments.asciidoc b/documentation/articles/UsingURIFragments.asciidoc
new file mode 100644 (file)
index 0000000..eebdf78
--- /dev/null
@@ -0,0 +1,87 @@
+[[using-uri-fragments]]
+Using URI fragments
+-------------------
+
+[[reading-fragment-when-initializing-ui]]
+Reading Fragment when Initializing UI
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+URI fragments can either be used for initializing the UI and/or read or
+modified in any listener. In the UI.init method you get a "VaadinRequest
+request" parameter. The UI's Page contains a information about the HTTP
+request used to initialize the application and you can get the URI
+fragment using
+
+....
+getPage().geUriFragment()
+....
+
+A simple init that depends on the URI fragment is thus:
+
+[source,java]
+....
+public class MyUI extends UI {
+  @Override
+  protected void init(VaadinRequest request) {
+    layout = new VerticalLayout();
+    layout.setMargin(true);
+    setContent(layout);
+
+    Label label = new Label("Hello, your fragment is "
+            + getPage().getUriFragment());
+    layout.addComponent(label);
+  }
+}
+....
+
+[[reading-fragment-changes]]
+Reading Fragment Changes
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The URI fragment can be changed also when the application is running,
+either manually in the location bar in browser or from user code. These
+changes can be caught with a **FragmentChangedListener**. Notice,
+however, that there is no event fired for the initial URL fragment. The
+easiest way to handle both cases in the same way is to call the same
+method from the FragmentChangedListener and the init method:
+
+[source,java]
+....
+public class MyUI extends UI {
+  // ...
+
+  // React to fragment changes
+  getPage().addUriFragmentChangedListener(new UriFragmentChangedListener() {
+    @Override
+    public void uriFragmentChanged(UriFragmentChangedEvent source) {
+      handleFragment(source.getUriFragment());
+    }
+  });
+
+  // Handle the fragment received in the initial request
+  handleFragment(getPage().getUriFragment());
+
+  addComponent(new Button("Show and set fragment", new Button.ClickListener() {
+    @Override
+      public void buttonClick(ClickEvent event) {
+        handleFragment(getPage().getUriFragment());
+        getPage().setUriFragment("customFragment");
+      }
+  }));
+....
+
+[[reading-and-writing-the-fragment]]
+Reading and Writing the Fragment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To later on read the fragment you can use
+
+....
+Page.getCurrent().getUriFragment();
+....
+
+and to set the fragment
+
+....
+Page.getCurrent().setUriFragment(String fragment);
+....
index f0dc2f97b52c49580e5b1c5d0d0290adda5d8460..4c850f012fdc9b667c6a68d103f5d5e3c7962501 100644 (file)
@@ -21,7 +21,7 @@ are great, too.
 - link:SendingEmailFromJavaApplications.asciidoc[Sending email from Java applications]
 - link:OptimizingSluggishUI.asciidoc[Optimizing sluggish UI]
 - link:UsingParametersWithViews.asciidoc[Using parameters with views]
-- link:ConfiguringPushForYourEnviroment.asciidoc[Configuring push for your environment]
+- link:ConfiguringPushForYourEnvironment.asciidoc[Configuring push for your environment]
 - link:SettingAndReadingCookies.asciidoc[Setting and reading cookies]
 - link:UsingPolling.asciidoc[Using polling]
 - link:FindingTheCurrentUIAndPageAndVaadinSession.asciidoc[Finding the current UI and page and Vaadin Session]
@@ -32,3 +32,6 @@ are great, too.
 - link:RememberToTheSetTheLocale.asciidoc[Remember to the set the locale]
 - link:MVCBasicsInITMillToolkit.asciidoc[MVC Basics in IT Mill Toolkit]
 - link:CustomizingTheStartupPageInAnApplication.asciidoc[Customizing the startup page in an application]
+- link:UsingURIFragments.asciidoc[Using URI fragments]
+- link:AccessingWebPageAndBrowserInformation.asciidoc[Accessing web page and browser information]
+- link:GeneratingDynamicResourcesBasedOnURIOrParameters.asciidoc[Generating dynamic resources based on URI or parameters]