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:43 UTC
[wicket] 01/01: create demo page showing how to use push in order
to update a component via web-sockets.
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;
+ }
+ }
+}