You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2016/10/14 10:39:18 UTC

svn commit: r1764860 - in /openmeetings/application: branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/ branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/ branches/3.2.x/openmeetings-db/s...

Author: solomax
Date: Fri Oct 14 10:39:18 2016
New Revision: 1764860

URL: http://svn.apache.org/viewvc?rev=1764860&view=rev
Log:
[OPENMEETINGS-895] Websocket ping every 30sec are added

Modified:
    openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java
    openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java

Modified: openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java?rev=1764860&r1=1764859&r2=1764860&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java Fri Oct 14 10:39:18 2016
@@ -34,16 +34,14 @@ import org.simpleframework.xml.Element;
 import org.simpleframework.xml.Root;
 
 @Entity
-@Table(name = "sipuser")
+@Table(name = "sipusers")
 @Root(name="asterisksipuser")
 public class AsteriskSipUser implements Serializable {
 	private static final long serialVersionUID = 1L;
-	
-	@XmlType(namespace="org.apache.openmeetings.user.asterisk")
+
+	@XmlType(namespace = "org.apache.openmeetings.user.asterisk")
 	public enum Type {
-		friend,
-		user,
-		peer
+		friend, user, peer
 	}
 
 	@Id
@@ -52,73 +50,73 @@ public class AsteriskSipUser implements
 	@Element(data = true)
 	private long id;
 
-	@Column(name = "type", nullable = false, length=6)
+	@Column(name = "type", nullable = false, length = 6)
 	@Enumerated(EnumType.STRING)
-	@Element(data=true, required=false)
+	@Element(data = true, required = false)
 	private Type type = Type.friend;
-	
-	@Column(name = "name", nullable = false, length=128)
-	@Element(data=true, required=false)
-	private String name = ""; //	Varchar 128
-	
-	@Column(name = "secret", length=128)
-	@Element(data=true, required = false)
-	private String secret; //	Varchar 128
-	
-	@Column(name = "context", length=128)
-	@Element(data=true, required = false)
-	private String context; //	Varchar 128
-	
-	@Column(name = "host", nullable = false, length=128)
-	@Element(data=true, required = false)
-	private String host = "dynamic"; //	Varchar 128
-	
-	@Column(name = "ipaddr", nullable = false, length=128)
-	@Element(data=true, required=false)
-	private String ipaddr = ""; //	Varchar 128
-	
-	@Column(name = "port", nullable = false, length=8)
-	@Element(data=true, required=false)
-	private Integer port = 0; //	mediumint(8)
-	
+
+	@Column(name = "name", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String name = ""; // Varchar 128
+
+	@Column(name = "secret", length = 128)
+	@Element(data = true, required = false)
+	private String secret; // Varchar 128
+
+	@Column(name = "context", length = 128)
+	@Element(data = true, required = false)
+	private String context; // Varchar 128
+
+	@Column(name = "host", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String host = "dynamic"; // Varchar 128
+
+	@Column(name = "ipaddr", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String ipaddr = ""; // Varchar 128
+
+	@Column(name = "port", nullable = false, length = 8)
+	@Element(data = true, required = false)
+	private Integer port = 0; // mediumint(8)
+
 	@Column(name = "regseconds", nullable = false)
-	@Element(data=true, required = false)
-	private Long regseconds = 0L; //	Bigint
-	
-	@Column(name = "defaultuser", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String defaultuser; //	Varchar 128
-	
-	@Column(name = "fullcontact", length=512)
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
+	private Long regseconds = 0L; // Bigint
+
+	@Column(name = "defaultuser", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String defaultuser; // Varchar 128
+
+	@Column(name = "fullcontact", length = 512)
+	@Element(data = true, required = false)
 	private String fullcontact;
-	
-	@Column(name = "regserver", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String regserver; //	Varchar 128
-	
-	@Column(name = "useragent", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String useragent; //	Varchar 128
-	
+
+	@Column(name = "regserver", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String regserver; // Varchar 128
+
+	@Column(name = "useragent", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String useragent; // Varchar 128
+
 	@Column(name = "lastms")
-	@Element(data=true, required = false)
-	private Integer lastms; //	Integer
-	
+	@Element(data = true, required = false)
+	private Integer lastms; // Integer
+
 	@Column(name = "md5secret")
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
 	private String md5secret;
 
-	@Column(name = "nat", nullable=false)
-	@Element(data=true, required = false)
+	@Column(name = "nat", nullable = false)
+	@Element(data = true, required = false)
 	private String nat = "force_rport,comedia";
-	
-	@Column(name = "callbackextension", nullable=true, length=250)
-	@Element(data=true, required = false)
+
+	@Column(name = "callbackextension", nullable = true, length = 250)
+	@Element(data = true, required = false)
 	private String callbackextension;
 
-	@Column(name = "allow", nullable=false, length=100)
-	@Element(data=true, required = false)
+	@Column(name = "allow", nullable = false, length = 100)
+	@Element(data = true, required = false)
 	private String allow = "ulaw;alaw;h264";
 
 	public long getId() {
@@ -264,4 +262,4 @@ public class AsteriskSipUser implements
 	public void setAllow(String allow) {
 		this.allow = allow;
 	}
-}
\ No newline at end of file
+}

Modified: openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java?rev=1764860&r1=1764859&r2=1764860&view=diff
==============================================================================
--- openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java (original)
+++ openmeetings/application/branches/3.1.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java Fri Oct 14 10:39:18 2016
@@ -31,6 +31,7 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.OmUrlFragment.getPanel;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -53,6 +54,7 @@ import org.apache.openmeetings.web.util.
 import org.apache.openmeetings.web.util.OmUrlFragment;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
@@ -66,11 +68,18 @@ import org.apache.wicket.markup.html.for
 import org.apache.wicket.markup.html.panel.EmptyPanel;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
 import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
+import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
 import org.apache.wicket.protocol.ws.api.message.AbortedMessage;
 import org.apache.wicket.protocol.ws.api.message.AbstractClientMessage;
 import org.apache.wicket.protocol.ws.api.message.ClosedMessage;
 import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
+import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
+import org.apache.wicket.protocol.ws.api.registry.PageIdKey;
+import org.apache.wicket.protocol.ws.concurrent.Executor;
+import org.apache.wicket.util.time.Duration;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.wicketstuff.urlfragment.UrlFragment;
@@ -90,6 +99,35 @@ public class MainPanel extends Panel {
 	private final ChatPanel chat;
 	private final MessageDialog newMessage;
 	private final UserInfoDialog userInfo;
+	private AbstractAjaxTimerBehavior pingTimer = new AbstractAjaxTimerBehavior(Duration.seconds(30)) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		protected void onTimer(AjaxRequestTarget target) {
+			if (client != null) {
+				WebSocketSettings settings = WebSocketSettings.Holder.get(Application.get());
+				IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
+				Executor executor = settings.getWebSocketPushMessageExecutor();
+				try {
+					final IWebSocketConnection wsConnection = reg.getConnection(Application.get(), client.getSessionId(), new PageIdKey(client.getPageId()));
+					if (wsConnection != null) {
+						executor.run(new Runnable() {
+							@Override
+							public void run() {
+								try {
+									wsConnection.sendMessage(new byte[1], 0, 1);
+								} catch (IOException e) {
+									log.error("Error while sending ping message to room", e);
+								}
+							}
+						});
+					}
+				} catch (Exception e) {
+					log.error("Error preparing executor", e);
+				}
+			}
+		}
+	};
 
 	public MainPanel(String id) {
 		this(id, new WebMarkupContainer(CHILD_ID));
@@ -166,7 +204,7 @@ public class MainPanel extends Panel {
 			protected void respond(AjaxRequestTarget target) {
 				ContactsHelper.addUserToContactList(getParam(getComponent(), PARAM_USER_ID).toLong());
 			}
-			
+
 			@Override
 			public void renderHead(Component component, IHeaderResponse response) {
 				super.renderHead(component, response);
@@ -180,14 +218,14 @@ public class MainPanel extends Panel {
 			protected void respond(AjaxRequestTarget target) {
 				newMessage.reset(true).open(target, getParam(getComponent(), PARAM_USER_ID).toOptionalLong());
 			}
-			
+
 			@Override
 			public void renderHead(Component component, IHeaderResponse response) {
 				super.renderHead(component, response);
 				response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forScript(getNamedFunction("privateMessage", this, explicit(PARAM_USER_ID)), "privateMessage")));
 			}
 		});
-		add(new WebSocketBehavior() {
+		add(pingTimer, new WebSocketBehavior() {
 			private static final long serialVersionUID = 1L;
 
 			@Override
@@ -203,7 +241,7 @@ public class MainPanel extends Panel {
 				super.onAbort(msg);
 				closeHandler(msg);
 			}
-			
+
 			@Override
 			protected void onClose(ClosedMessage msg) {
 				super.onClose(msg);
@@ -211,6 +249,7 @@ public class MainPanel extends Panel {
 			}
 
 			private void closeHandler(AbstractClientMessage msg) {
+				//no chance to stop pingTimer here :(
 				log.debug("WebSocketBehavior::closeHandler [uid: {}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
 				removeOnlineUser(client);
 				client = null;

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java?rev=1764860&r1=1764859&r2=1764860&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java Fri Oct 14 10:39:18 2016
@@ -38,12 +38,10 @@ import org.simpleframework.xml.Root;
 @Root(name="asterisksipuser")
 public class AsteriskSipUser implements Serializable {
 	private static final long serialVersionUID = 1L;
-	
-	@XmlType(namespace="org.apache.openmeetings.user.asterisk")
+
+	@XmlType(namespace = "org.apache.openmeetings.user.asterisk")
 	public enum Type {
-		friend,
-		user,
-		peer
+		friend, user, peer
 	}
 
 	@Id
@@ -52,73 +50,73 @@ public class AsteriskSipUser implements
 	@Element(data = true)
 	private long id;
 
-	@Column(name = "type", nullable = false, length=6)
+	@Column(name = "type", nullable = false, length = 6)
 	@Enumerated(EnumType.STRING)
-	@Element(data=true, required=false)
+	@Element(data = true, required = false)
 	private Type type = Type.friend;
-	
-	@Column(name = "name", nullable = false, length=128)
-	@Element(data=true, required=false)
-	private String name = ""; //	Varchar 128
-	
-	@Column(name = "secret", length=128)
-	@Element(data=true, required = false)
-	private String secret; //	Varchar 128
-	
-	@Column(name = "context", length=128)
-	@Element(data=true, required = false)
-	private String context; //	Varchar 128
-	
-	@Column(name = "host", nullable = false, length=128)
-	@Element(data=true, required = false)
-	private String host = "dynamic"; //	Varchar 128
-	
-	@Column(name = "ipaddr", nullable = false, length=128)
-	@Element(data=true, required=false)
-	private String ipaddr = ""; //	Varchar 128
-	
-	@Column(name = "port", nullable = false, length=8)
-	@Element(data=true, required=false)
-	private Integer port = 0; //	mediumint(8)
-	
+
+	@Column(name = "name", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String name = ""; // Varchar 128
+
+	@Column(name = "secret", length = 128)
+	@Element(data = true, required = false)
+	private String secret; // Varchar 128
+
+	@Column(name = "context", length = 128)
+	@Element(data = true, required = false)
+	private String context; // Varchar 128
+
+	@Column(name = "host", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String host = "dynamic"; // Varchar 128
+
+	@Column(name = "ipaddr", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String ipaddr = ""; // Varchar 128
+
+	@Column(name = "port", nullable = false, length = 8)
+	@Element(data = true, required = false)
+	private Integer port = 0; // mediumint(8)
+
 	@Column(name = "regseconds", nullable = false)
-	@Element(data=true, required = false)
-	private Long regseconds = 0L; //	Bigint
-	
-	@Column(name = "defaultuser", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String defaultuser; //	Varchar 128
-	
-	@Column(name = "fullcontact", length=512)
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
+	private Long regseconds = 0L; // Bigint
+
+	@Column(name = "defaultuser", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String defaultuser; // Varchar 128
+
+	@Column(name = "fullcontact", length = 512)
+	@Element(data = true, required = false)
 	private String fullcontact;
-	
-	@Column(name = "regserver", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String regserver; //	Varchar 128
-	
-	@Column(name = "useragent", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String useragent; //	Varchar 128
-	
+
+	@Column(name = "regserver", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String regserver; // Varchar 128
+
+	@Column(name = "useragent", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String useragent; // Varchar 128
+
 	@Column(name = "lastms")
-	@Element(data=true, required = false)
-	private Integer lastms; //	Integer
-	
+	@Element(data = true, required = false)
+	private Integer lastms; // Integer
+
 	@Column(name = "md5secret")
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
 	private String md5secret;
 
-	@Column(name = "nat", nullable=false)
-	@Element(data=true, required = false)
+	@Column(name = "nat", nullable = false)
+	@Element(data = true, required = false)
 	private String nat = "force_rport,comedia";
-	
-	@Column(name = "callbackextension", nullable=true, length=250)
-	@Element(data=true, required = false)
+
+	@Column(name = "callbackextension", nullable = true, length = 250)
+	@Element(data = true, required = false)
 	private String callbackextension;
 
-	@Column(name = "allow", nullable=false, length=100)
-	@Element(data=true, required = false)
+	@Column(name = "allow", nullable = false, length = 100)
+	@Element(data = true, required = false)
 	private String allow = "ulaw;alaw;h264";
 
 	public long getId() {
@@ -264,4 +262,4 @@ public class AsteriskSipUser implements
 	public void setAllow(String allow) {
 		this.allow = allow;
 	}
-}
\ No newline at end of file
+}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java?rev=1764860&r1=1764859&r2=1764860&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java Fri Oct 14 10:39:18 2016
@@ -31,6 +31,7 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.OmUrlFragment.getPanel;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -54,6 +55,7 @@ import org.apache.openmeetings.web.util.
 import org.apache.openmeetings.web.util.OmUrlFragment;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
@@ -67,6 +69,8 @@ import org.apache.wicket.markup.html.for
 import org.apache.wicket.markup.html.panel.EmptyPanel;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
 import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
 import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
 import org.apache.wicket.protocol.ws.api.message.AbortedMessage;
@@ -74,6 +78,10 @@ import org.apache.wicket.protocol.ws.api
 import org.apache.wicket.protocol.ws.api.message.ClosedMessage;
 import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
 import org.apache.wicket.protocol.ws.api.message.TextMessage;
+import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
+import org.apache.wicket.protocol.ws.api.registry.PageIdKey;
+import org.apache.wicket.protocol.ws.concurrent.Executor;
+import org.apache.wicket.util.time.Duration;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.wicketstuff.urlfragment.UrlFragment;
@@ -95,6 +103,35 @@ public class MainPanel extends Panel {
 	private final MessageDialog newMessage;
 	private final UserInfoDialog userInfo;
 	private BasePanel panel;
+	private AbstractAjaxTimerBehavior pingTimer = new AbstractAjaxTimerBehavior(Duration.seconds(30)) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		protected void onTimer(AjaxRequestTarget target) {
+			if (client != null) {
+				WebSocketSettings settings = WebSocketSettings.Holder.get(Application.get());
+				IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
+				Executor executor = settings.getWebSocketPushMessageExecutor();
+				try {
+					final IWebSocketConnection wsConnection = reg.getConnection(Application.get(), client.getSessionId(), new PageIdKey(client.getPageId()));
+					if (wsConnection != null) {
+						executor.run(new Runnable() {
+							@Override
+							public void run() {
+								try {
+									wsConnection.sendMessage(new byte[1], 0, 1);
+								} catch (IOException e) {
+									log.error("Error while sending ping message to room", e);
+								}
+							}
+						});
+					}
+				} catch (Exception e) {
+					log.error("Error preparing executor", e);
+				}
+			}
+		}
+	};
 
 	public MainPanel(String id) {
 		this(id, null);
@@ -172,7 +209,7 @@ public class MainPanel extends Panel {
 			protected void respond(AjaxRequestTarget target) {
 				ContactsHelper.addUserToContactList(getParam(getComponent(), PARAM_USER_ID).toLong());
 			}
-			
+
 			@Override
 			public void renderHead(Component component, IHeaderResponse response) {
 				super.renderHead(component, response);
@@ -186,14 +223,14 @@ public class MainPanel extends Panel {
 			protected void respond(AjaxRequestTarget target) {
 				newMessage.reset(true).open(target, getParam(getComponent(), PARAM_USER_ID).toOptionalLong());
 			}
-			
+
 			@Override
 			public void renderHead(Component component, IHeaderResponse response) {
 				super.renderHead(component, response);
 				response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forScript(getNamedFunction("privateMessage", this, explicit(PARAM_USER_ID)), "privateMessage")));
 			}
 		});
-		add(new WebSocketBehavior() {
+		add(pingTimer, new WebSocketBehavior() {
 			private static final long serialVersionUID = 1L;
 
 			@Override
@@ -218,14 +255,15 @@ public class MainPanel extends Panel {
 				super.onAbort(msg);
 				closeHandler(msg);
 			}
-			
+
 			@Override
 			protected void onClose(ClosedMessage msg) {
 				super.onClose(msg);
 				closeHandler(msg);
 			}
-			
+
 			private void closeHandler(AbstractClientMessage msg) {
+				//no chance to stop pingTimer here :(
 				if (client != null && client.getRoomId() != null) {
 					RoomMenuPanel.roomExit(client);
 				}

Modified: openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java?rev=1764860&r1=1764859&r2=1764860&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java (original)
+++ openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/user/AsteriskSipUser.java Fri Oct 14 10:39:18 2016
@@ -38,12 +38,10 @@ import org.simpleframework.xml.Root;
 @Root(name="asterisksipuser")
 public class AsteriskSipUser implements Serializable {
 	private static final long serialVersionUID = 1L;
-	
-	@XmlType(namespace="org.apache.openmeetings.user.asterisk")
+
+	@XmlType(namespace = "org.apache.openmeetings.user.asterisk")
 	public enum Type {
-		friend,
-		user,
-		peer
+		friend, user, peer
 	}
 
 	@Id
@@ -52,73 +50,73 @@ public class AsteriskSipUser implements
 	@Element(data = true)
 	private long id;
 
-	@Column(name = "type", nullable = false, length=6)
+	@Column(name = "type", nullable = false, length = 6)
 	@Enumerated(EnumType.STRING)
-	@Element(data=true, required=false)
+	@Element(data = true, required = false)
 	private Type type = Type.friend;
-	
-	@Column(name = "name", nullable = false, length=128)
-	@Element(data=true, required=false)
-	private String name = ""; //	Varchar 128
-	
-	@Column(name = "secret", length=128)
-	@Element(data=true, required = false)
-	private String secret; //	Varchar 128
-	
-	@Column(name = "context", length=128)
-	@Element(data=true, required = false)
-	private String context; //	Varchar 128
-	
-	@Column(name = "host", nullable = false, length=128)
-	@Element(data=true, required = false)
-	private String host = "dynamic"; //	Varchar 128
-	
-	@Column(name = "ipaddr", nullable = false, length=128)
-	@Element(data=true, required=false)
-	private String ipaddr = ""; //	Varchar 128
-	
-	@Column(name = "port", nullable = false, length=8)
-	@Element(data=true, required=false)
-	private Integer port = 0; //	mediumint(8)
-	
+
+	@Column(name = "name", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String name = ""; // Varchar 128
+
+	@Column(name = "secret", length = 128)
+	@Element(data = true, required = false)
+	private String secret; // Varchar 128
+
+	@Column(name = "context", length = 128)
+	@Element(data = true, required = false)
+	private String context; // Varchar 128
+
+	@Column(name = "host", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String host = "dynamic"; // Varchar 128
+
+	@Column(name = "ipaddr", nullable = false, length = 128)
+	@Element(data = true, required = false)
+	private String ipaddr = ""; // Varchar 128
+
+	@Column(name = "port", nullable = false, length = 8)
+	@Element(data = true, required = false)
+	private Integer port = 0; // mediumint(8)
+
 	@Column(name = "regseconds", nullable = false)
-	@Element(data=true, required = false)
-	private Long regseconds = 0L; //	Bigint
-	
-	@Column(name = "defaultuser", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String defaultuser; //	Varchar 128
-	
-	@Column(name = "fullcontact", length=512)
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
+	private Long regseconds = 0L; // Bigint
+
+	@Column(name = "defaultuser", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String defaultuser; // Varchar 128
+
+	@Column(name = "fullcontact", length = 512)
+	@Element(data = true, required = false)
 	private String fullcontact;
-	
-	@Column(name = "regserver", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String regserver; //	Varchar 128
-	
-	@Column(name = "useragent", nullable = true, length=128)
-	@Element(data=true, required = false)
-	private String useragent; //	Varchar 128
-	
+
+	@Column(name = "regserver", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String regserver; // Varchar 128
+
+	@Column(name = "useragent", nullable = true, length = 128)
+	@Element(data = true, required = false)
+	private String useragent; // Varchar 128
+
 	@Column(name = "lastms")
-	@Element(data=true, required = false)
-	private Integer lastms; //	Integer
-	
+	@Element(data = true, required = false)
+	private Integer lastms; // Integer
+
 	@Column(name = "md5secret")
-	@Element(data=true, required = false)
+	@Element(data = true, required = false)
 	private String md5secret;
 
-	@Column(name = "nat", nullable=false)
-	@Element(data=true, required = false)
+	@Column(name = "nat", nullable = false)
+	@Element(data = true, required = false)
 	private String nat = "force_rport,comedia";
-	
-	@Column(name = "callbackextension", nullable=true, length=250)
-	@Element(data=true, required = false)
+
+	@Column(name = "callbackextension", nullable = true, length = 250)
+	@Element(data = true, required = false)
 	private String callbackextension;
 
-	@Column(name = "allow", nullable=false, length=100)
-	@Element(data=true, required = false)
+	@Column(name = "allow", nullable = false, length = 100)
+	@Element(data = true, required = false)
 	private String allow = "ulaw;alaw;h264";
 
 	public long getId() {
@@ -264,4 +262,4 @@ public class AsteriskSipUser implements
 	public void setAllow(String allow) {
 		this.allow = allow;
 	}
-}
\ No newline at end of file
+}

Modified: openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java?rev=1764860&r1=1764859&r2=1764860&view=diff
==============================================================================
--- openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java (original)
+++ openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java Fri Oct 14 10:39:18 2016
@@ -31,6 +31,7 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.OmUrlFragment.getPanel;
 import static org.apache.wicket.ajax.attributes.CallbackParameter.explicit;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -54,6 +55,7 @@ import org.apache.openmeetings.web.util.
 import org.apache.openmeetings.web.util.OmUrlFragment;
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.AjaxLink;
@@ -67,6 +69,8 @@ import org.apache.wicket.markup.html.for
 import org.apache.wicket.markup.html.panel.EmptyPanel;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.protocol.ws.WebSocketSettings;
+import org.apache.wicket.protocol.ws.api.IWebSocketConnection;
 import org.apache.wicket.protocol.ws.api.WebSocketBehavior;
 import org.apache.wicket.protocol.ws.api.WebSocketRequestHandler;
 import org.apache.wicket.protocol.ws.api.message.AbortedMessage;
@@ -74,6 +78,10 @@ import org.apache.wicket.protocol.ws.api
 import org.apache.wicket.protocol.ws.api.message.ClosedMessage;
 import org.apache.wicket.protocol.ws.api.message.ConnectedMessage;
 import org.apache.wicket.protocol.ws.api.message.TextMessage;
+import org.apache.wicket.protocol.ws.api.registry.IWebSocketConnectionRegistry;
+import org.apache.wicket.protocol.ws.api.registry.PageIdKey;
+import org.apache.wicket.protocol.ws.concurrent.Executor;
+import org.apache.wicket.util.time.Duration;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import org.wicketstuff.urlfragment.UrlFragment;
@@ -95,6 +103,35 @@ public class MainPanel extends Panel {
 	private final MessageDialog newMessage;
 	private final UserInfoDialog userInfo;
 	private BasePanel panel;
+	private AbstractAjaxTimerBehavior pingTimer = new AbstractAjaxTimerBehavior(Duration.seconds(30)) {
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		protected void onTimer(AjaxRequestTarget target) {
+			if (client != null) {
+				WebSocketSettings settings = WebSocketSettings.Holder.get(Application.get());
+				IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
+				Executor executor = settings.getWebSocketPushMessageExecutor();
+				try {
+					final IWebSocketConnection wsConnection = reg.getConnection(Application.get(), client.getSessionId(), new PageIdKey(client.getPageId()));
+					if (wsConnection != null) {
+						executor.run(new Runnable() {
+							@Override
+							public void run() {
+								try {
+									wsConnection.sendMessage(new byte[1], 0, 1);
+								} catch (IOException e) {
+									log.error("Error while sending ping message to room", e);
+								}
+							}
+						});
+					}
+				} catch (Exception e) {
+					log.error("Error preparing executor", e);
+				}
+			}
+		}
+	};
 
 	public MainPanel(String id) {
 		this(id, null);
@@ -172,7 +209,7 @@ public class MainPanel extends Panel {
 			protected void respond(AjaxRequestTarget target) {
 				ContactsHelper.addUserToContactList(getParam(getComponent(), PARAM_USER_ID).toLong());
 			}
-			
+
 			@Override
 			public void renderHead(Component component, IHeaderResponse response) {
 				super.renderHead(component, response);
@@ -186,14 +223,14 @@ public class MainPanel extends Panel {
 			protected void respond(AjaxRequestTarget target) {
 				newMessage.reset(true).open(target, getParam(getComponent(), PARAM_USER_ID).toOptionalLong());
 			}
-			
+
 			@Override
 			public void renderHead(Component component, IHeaderResponse response) {
 				super.renderHead(component, response);
 				response.render(new PriorityHeaderItem(JavaScriptHeaderItem.forScript(getNamedFunction("privateMessage", this, explicit(PARAM_USER_ID)), "privateMessage")));
 			}
 		});
-		add(new WebSocketBehavior() {
+		add(pingTimer, new WebSocketBehavior() {
 			private static final long serialVersionUID = 1L;
 
 			@Override
@@ -218,14 +255,15 @@ public class MainPanel extends Panel {
 				super.onAbort(msg);
 				closeHandler(msg);
 			}
-			
+
 			@Override
 			protected void onClose(ClosedMessage msg) {
 				super.onClose(msg);
 				closeHandler(msg);
 			}
-			
+
 			private void closeHandler(AbstractClientMessage msg) {
+				//no chance to stop pingTimer here :(
 				if (client != null && client.getRoomId() != null) {
 					RoomMenuPanel.roomExit(client);
 				}