You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by re...@apache.org on 2021/05/20 09:00:42 UTC

[wicket] branch update-component-example created (now 0f580b9)

This is an automated email from the ASF dual-hosted git repository.

reiern70 pushed a change to branch update-component-example
in repository https://gitbox.apache.org/repos/asf/wicket.git.


      at 0f580b9  create demo page showing how to use push in order to update a component via web-sockets.

This branch includes the following new commits:

     new 0f580b9  create demo page showing how to use push in order to update a component via web-sockets.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[wicket] 01/01: create demo page showing how to use push in order to update a component via web-sockets.

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

reiern70 pushed a commit to branch update-component-example
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit 0f580b978fa0c254c97954846d87c7330938077c
Author: ernestosemedy <ba...@semedy.com>
AuthorDate: Thu May 20 12:00:23 2021 +0300

    create demo page showing how to use push in order to update a component via web-sockets.
---
 .../apache/wicket/examples/websocket/HomePage.html |   1 +
 .../examples/websocket/JSR356Application.java      |   1 +
 .../WebSocketPushUpdateProgressDemoPage.html       |   8 ++
 .../WebSocketPushUpdateProgressDemoPage.java       |  30 ++++
 .../ProgressBarTogglePanel.html}                   |  30 ++--
 .../websocket/progress/ProgressBarTogglePanel.java | 133 ++++++++++++++++++
 .../websocket/progress/ProgressUpdater.java        | 155 +++++++++++++++++++++
 7 files changed, 338 insertions(+), 20 deletions(-)

diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/HomePage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/HomePage.html
index 3821f67..74b2062 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/HomePage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/HomePage.html
@@ -29,6 +29,7 @@
 					<li><a href="WebSocketBehaviorDemoPage.html">demo with WebSocketBehavior</a></li>
 					<li><a href="WebSocketResourceDemoPage.html">demo with WebSocketResource</a></li>
 					<li><a href="WebSocketMultiTabResourceDemoPage.html">demo with WebSocketResource and multiple tabs</a></li>
+					<li><a href="WebSocketPushUpdateProgressDemoPage.html">Update a component via push notifications</a></li>
 				</ul>
 			</wicket:link>
 		</wicket:extend>
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/JSR356Application.java b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/JSR356Application.java
index bb38205..31615ed 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/JSR356Application.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/JSR356Application.java
@@ -50,6 +50,7 @@ public class JSR356Application extends WicketExampleApplication
 		setRootRequestMapper(new HttpsMapper(getRootRequestMapper(), new HttpsConfig(8080, 8443)));
 
 		mountPage("/behavior", WebSocketBehaviorDemoPage.class);
+		mountPage("/progress", WebSocketPushUpdateProgressDemoPage.class);
 		mountPage("/resource", WebSocketResourceDemoPage.class);
 		mountPage("/resource-multi-tab", WebSocketMultiTabResourceDemoPage.class);
 
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/WebSocketPushUpdateProgressDemoPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/WebSocketPushUpdateProgressDemoPage.html
new file mode 100644
index 0000000..55210d3
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/WebSocketPushUpdateProgressDemoPage.html
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+<body>
+<wicket:extend>
+    <div wicket:id="progressPanel"></div>
+</wicket:extend>
+</body>
+</html>
\ No newline at end of file
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/WebSocketPushUpdateProgressDemoPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/WebSocketPushUpdateProgressDemoPage.java
new file mode 100644
index 0000000..01d16b2
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/WebSocketPushUpdateProgressDemoPage.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.examples.websocket;
+
+import org.apache.wicket.examples.WicketExamplePage;
+import org.apache.wicket.examples.websocket.progress.ProgressBarTogglePanel;
+import org.apache.wicket.protocol.https.RequireHttps;
+
+@RequireHttps
+public class WebSocketPushUpdateProgressDemoPage extends WicketExamplePage
+{
+	public WebSocketPushUpdateProgressDemoPage()
+	{
+		add(new ProgressBarTogglePanel("progressPanel"));
+	}
+}
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/HomePage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressBarTogglePanel.html
similarity index 56%
copy from wicket-examples/src/main/java/org/apache/wicket/examples/websocket/HomePage.html
copy to wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressBarTogglePanel.html
index 3821f67..971f7f2 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/HomePage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressBarTogglePanel.html
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8" ?>
+<?xml version="1.0" encoding="UTF-8"?>
 <!--
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
@@ -15,22 +15,12 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 -->
-<!DOCTYPE html>
-<html xmlns:wicket="http://wicket.apache.org">
-	<head>
-		<meta charset="utf-8" />
-        <title>Apache Wicket Native WebSocket demos</title>
-	</head>
-	<body>
-		<wicket:extend>
-
-			<wicket:link>
-				<ul>
-					<li><a href="WebSocketBehaviorDemoPage.html">demo with WebSocketBehavior</a></li>
-					<li><a href="WebSocketResourceDemoPage.html">demo with WebSocketResource</a></li>
-					<li><a href="WebSocketMultiTabResourceDemoPage.html">demo with WebSocketResource and multiple tabs</a></li>
-				</ul>
-			</wicket:link>
-		</wicket:extend>
-	</body>
-</html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+<body>
+<wicket:panel>
+    <div><a wicket:id="hideShowProgress"></a></div>
+    <div><a wicket:id="cancelRestartTask"></a></div>
+    <div wicket:id="progressBar"></div>
+</wicket:panel>
+</body>
+</html>
\ No newline at end of file
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressBarTogglePanel.java b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressBarTogglePanel.java
new file mode 100644
index 0000000..3fd364a
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressBarTogglePanel.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.examples.websocket.progress;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.markup.html.AjaxLink;
+import org.apache.wicket.event.IEvent;
+import org.apache.wicket.examples.websocket.JSR356Application;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.panel.Panel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.event.WebSocketPushPayload;
+import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
+
+public class ProgressBarTogglePanel extends Panel
+{
+
+    private int progress = 0;
+    private boolean showProgress = true;
+    private ProgressUpdater.ProgressUpdateTask progressUpdateTask;
+
+    public ProgressBarTogglePanel(String id)
+    {
+        super(id);
+
+        setOutputMarkupId(true);
+
+        add(new WebSocketBehavior()
+        {
+            @Override
+            protected void onConnect(ConnectedMessage message) {
+                progressUpdateTask = ProgressBarTogglePanel.startProgressTask(message);
+            }
+        });
+
+        add(new AjaxLink<Void>("hideShowProgress")
+        {
+            @Override
+            public void onClick(AjaxRequestTarget target)
+            {
+                showProgress = !showProgress;
+                target.add(ProgressBarTogglePanel.this);
+            }
+        }.setBody(new IModel<String>()
+        {
+            @Override
+            public String getObject()
+            {
+                return showProgress ? "Hide progress" : "Show progress";
+            }
+        }));
+
+        add(new AjaxLink<Void>("cancelRestartTask")
+        {
+            @Override
+            public void onClick(AjaxRequestTarget target)
+            {
+                if (progressUpdateTask.isRunning() && !progressUpdateTask.isCanceled())
+                {
+                    progressUpdateTask.cancel();
+                }
+                else
+                {
+                    ScheduledExecutorService service = JSR356Application.get().getScheduledExecutorService();
+                    ProgressUpdater.restart(progressUpdateTask, service);
+                }
+                target.add(ProgressBarTogglePanel.this);
+            }
+        }.setBody(new IModel<String>()
+        {
+            @Override
+            public String getObject()
+            {
+                return progressUpdateTask != null && progressUpdateTask.isRunning() && !progressUpdateTask.isCanceled() ? "Cancel task" : "Restart task";
+            }
+        }));
+
+        add(new Label("progressBar", new IModel<String>()
+        {
+            @Override
+            public String getObject()
+            {
+                return progressUpdateTask != null && progressUpdateTask.isRunning() ? "Background Task is " + progress + "% completed" : "No task is running";
+            }
+        })
+        {
+            @Override
+            protected void onConfigure()
+            {
+                super.onConfigure();
+                setVisible(showProgress);
+            }
+        });
+    }
+
+    public static ProgressUpdater.ProgressUpdateTask startProgressTask(ConnectedMessage message)
+    {
+        ScheduledExecutorService service = JSR356Application.get().getScheduledExecutorService();
+        return ProgressUpdater.start(message, service);
+    }
+
+    @Override
+    public void onEvent(IEvent<?> event)
+    {
+        if (event.getPayload() instanceof WebSocketPushPayload)
+        {
+            WebSocketPushPayload wsEvent = (WebSocketPushPayload) event.getPayload();
+            if (wsEvent.getMessage() instanceof ProgressUpdater.ProgressUpdate)
+            {
+                ProgressUpdater.ProgressUpdate progressUpdate = (ProgressUpdater.ProgressUpdate)wsEvent.getMessage();
+                progress = progressUpdate.getProgress();
+                wsEvent.getHandler().add(this);
+            }
+        }
+    }
+}
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressUpdater.java b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressUpdater.java
new file mode 100644
index 0000000..e681f92
--- /dev/null
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/websocket/progress/ProgressUpdater.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.examples.websocket.progress;
+
+import java.io.Serializable;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
+import org.apache.wicket.protocol.ws.api.WebSocketPushBroadcaster;
+import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
+import org.apache.wicket.protocol.ws.api.message.IWebSocketPushMessage;
+import org.apache.wicket.protocol.ws.api.registry.IKey;
+import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
+
+/**
+ * A helper class that uses the web connection to push components updates to the client.
+ */
+public class ProgressUpdater
+{
+	public static ProgressUpdateTask start(ConnectedMessage message, ScheduledExecutorService scheduledExecutorService)
+	{
+		// create an asynchronous task that will write the data to the client
+		ProgressUpdateTask progressUpdateTask = new ProgressUpdateTask(message.getApplication(), message.getSessionId(), message.getKey());
+        scheduledExecutorService.schedule(progressUpdateTask, 1, TimeUnit.SECONDS);
+		return progressUpdateTask;
+	}
+
+	public static void restart(ProgressUpdateTask progressUpdateTask, ScheduledExecutorService scheduledExecutorService) {
+		scheduledExecutorService.schedule(progressUpdateTask, 1, TimeUnit.SECONDS);
+	}
+
+	/**
+	 * A push message used to update progress.
+	 */
+	public static class ProgressUpdate implements IWebSocketPushMessage
+	{
+
+		private final int progress;
+
+		public ProgressUpdate(int progress)
+		{
+			this.progress = progress;
+		}
+
+		public int getProgress()
+		{
+			return progress;
+		}
+	}
+
+	/**
+	 * A task that sends data to the client by pushing it to the web socket connection
+	 */
+	public static class ProgressUpdateTask implements Runnable, Serializable
+	{
+		/**
+		 * The following fields are needed to be able to lookup the IWebSocketConnection from
+		 * IWebSocketConnectionRegistry
+		 */
+		private final String applicationName;
+		private final String sessionId;
+		private final IKey key;
+
+		private boolean canceled = false;
+		private boolean running = false;
+
+		private ProgressUpdateTask(Application application, String sessionId, IKey key)
+		{
+			this.applicationName = application.getName();
+			this.sessionId = sessionId;
+			this.key = key;
+		}
+
+		@Override
+		public void run()
+		{
+			running = true;
+			Application application = Application.get(applicationName);
+			WebSocketSettings webSocketSettings = WebSocketSettings.Holder.get(application);
+			IWebSocketConnectionRegistry webSocketConnectionRegistry = webSocketSettings.getConnectionRegistry();
+
+			int progress = 0;
+
+			while (progress <= 100)
+			{
+				IWebSocketConnection connection = webSocketConnectionRegistry.getConnection(application, sessionId, key);
+				try
+				{
+					if (connection == null || !connection.isOpen())
+					{
+						running = false;
+						// stop if the web socket connection is closed
+						return;
+					}
+
+					if (canceled)
+					{
+						canceled = false;
+						running = false;
+						return;
+					}
+
+					WebSocketPushBroadcaster broadcaster =
+							new WebSocketPushBroadcaster(webSocketSettings.getConnectionRegistry());
+					broadcaster.broadcast(new ConnectedMessage(application, sessionId, key), new ProgressUpdate(progress));
+
+					// sleep for a while to simulate work
+					TimeUnit.SECONDS.sleep(1);
+					progress++;
+				}
+				catch (InterruptedException x)
+				{
+					Thread.currentThread().interrupt();
+					break;
+				}
+				catch (Exception e)
+				{
+					e.printStackTrace();
+					break;
+				}
+			}
+			running = false;
+		}
+
+		public boolean isRunning() {
+			return running;
+		}
+
+		public boolean isCanceled() {
+			return canceled;
+		}
+
+		public void cancel() {
+			this.canceled = true;
+			this.running = false;
+		}
+	}
+}