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 2017/02/16 04:15:28 UTC

svn commit: r1783168 [1/4] - in /openmeetings/application: branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ branches/3.2.x/openm...

Author: solomax
Date: Thu Feb 16 04:15:27 2017
New Revision: 1783168

URL: http://svn.apache.org/viewvc?rev=1783168&view=rev
Log:
[OPENMEETINGS-1553] basic mobile login is fixed

Added:
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
      - copied, changed from r1783167, openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java
      - copied, changed from r1783167, openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
Removed:
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
Modified:
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
    openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
    openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
    openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx
    openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/mainMethods.lzx
    openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/CreatePollDialog.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/ClientIconsPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/SelfIconsPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ClientIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/CamActivityIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/MicActivityIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/RoomActivityIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/AudioRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ExclusiveRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ModeratorRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RemoteControlRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ScreenShareRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/VideoRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/WhiteboardRightIcon.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
    openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomsPanel.java
    openmeetings/application/branches/3.2.x/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
    openmeetings/application/trunk/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
    openmeetings/application/trunk/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
    openmeetings/application/trunk/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/common/MainPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/StartSharingButton.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/poll/CreatePollDialog.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/ClientIconsPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/SelfIconsPanel.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ClientIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/SettingsIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/CamActivityIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/MicActivityIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/activity/RoomActivityIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/AudioRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ExclusiveRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ModeratorRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RemoteControlRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/RoomRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/ScreenShareRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/VideoRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/right/WhiteboardRightIcon.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/chat/Chat.java
    openmeetings/application/trunk/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/rooms/RoomsPanel.java
    openmeetings/application/trunk/openmeetings-webservice/src/main/java/org/apache/openmeetings/webservice/RoomWebService.java

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/MobileService.java Thu Feb 16 04:15:27 2017
@@ -25,13 +25,12 @@ import static org.apache.openmeetings.ut
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_OAUTH_REGISTER_KEY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_SOAP_REGISTER_KEY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.util.Version.getVersion;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -85,6 +84,11 @@ public class MobileService {
 		m.put(key, v == null ? "" : v);
 	}
 
+	public String refreshSession(String sid) {
+		sessionDao.check(sid);
+		return "ok";
+	}
+
 	public Map<String, Object> checkServer() {
 		Map<String, Object> result = new Hashtable<>();
 		result.put("allowSelfRegister",  "1".equals(cfgDao.getConfValue(CONFIG_FRONTEND_REGISTER_KEY, String.class, "0")));
@@ -191,23 +195,21 @@ public class MobileService {
 
 	private Map<String, Object> login(User u, Map<String, Object> result) {
 		if (u != null) {
-			Sessiondata sd = sessionDao.create(u.getId(), u.getLanguageId());
 			IConnection conn = Red5.getConnectionLocal();
 			String streamId = conn.getClient().getId();
 			Client c = sessionManager.getClientByStreamId(streamId, null);
 			if (c == null) {
-				c = sessionManager.addClientListItem(streamId, conn.getScope().getName(), conn.getRemotePort(),
-					conn.getRemoteAddress(), "", null);
-			}
-			if (c == null) {
 				// Failed to create client
 				result.put("status", -1);
 			} else {
+				Sessiondata sd = sessionDao.check(c.getSecurityCode());
+				sd.setUserId(u.getId());
+				sd.setLanguageId(u.getLanguageId());
+				sessionDao.update(sd);
 				SessionVariablesUtil.initClient(conn.getClient(), c.getPublicSID());
 				c.setUserId(u.getId());
 				c.setFirstname(u.getFirstname());
 				c.setLastname(u.getLastname());
-				c.setMobile(true);
 				sessionManager.updateClientByStreamId(streamId, c, false, null);
 
 				add(result, "sid", sd.getSessionId());
@@ -219,6 +221,7 @@ public class MobileService {
 				add(result, "login", u.getLogin());
 				add(result, "email", u.getAddress() == null ? "" : u.getAddress().getEmail());
 				add(result, "language", u.getLanguageId()); //TODO rights
+				add(result, "version", getVersion());
 			}
 		}
 		return result;
@@ -253,7 +256,7 @@ public class MobileService {
 	}
 
 	private void addRoom(String type, String org, boolean first, List<Map<String, Object>> result, Room r) {
-		Map<String, Object> room = new Hashtable<String, Object>();
+		Map<String, Object> room = new Hashtable<>();
 		room.put("id", r.getId());
 		room.put("name", r.getName());
 		room.put("type", type);
@@ -269,13 +272,13 @@ public class MobileService {
 	}
 
 	public List<Map<String, Object>> getRooms() {
-		List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
+		List<Map<String, Object>> result = new ArrayList<>();
 		// FIXME duplicated code
 		IConnection current = Red5.getConnectionLocal();
 		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		User u = userDao.get(c.getUserId());
 		//my rooms
-		List<Room> myl = new ArrayList<Room>();
+		List<Room> myl = new ArrayList<>();
 		myl.add(roomDao.getUserRoom(u.getId(), Room.Type.conference, labelDao.getString(1306L, u.getLanguageId())));
 		myl.add(roomDao.getUserRoom(u.getId(), Room.Type.restricted, labelDao.getString(1307L, u.getLanguageId())));
 		myl.addAll(roomDao.getAppointedRoomsByUser(u.getId()));
@@ -301,7 +304,8 @@ public class MobileService {
 	}
 
 	public Map<String, Object> roomConnect(String SID, Long userId) {
-		Map<String, Object> result = new Hashtable<String, Object>();
+		Map<String, Object> result = new Hashtable<>();
+		/** FIXME TODO
 		User u = userDao.get(userId);
 		Client c = scopeAdapter.setUsernameReconnect(SID, userId, u.getLogin(), u.getFirstname(), u.getLastname(), u.getPictureuri());
 		 //TODO check if we need anything here
@@ -317,6 +321,7 @@ public class MobileService {
 		result.put("publicSid", c.getPublicSID());
 
 		scopeAdapter.sendMessageToCurrentScope("addNewUser", c, false, false);
+		*/
 		return result;
 	}
 
@@ -324,16 +329,16 @@ public class MobileService {
 		IConnection current = Red5.getConnectionLocal();
 		Client c = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		c.setAvsettings(avMode);
-		c.setVWidth(Integer.parseInt(width));
-		c.setVHeight(Integer.parseInt(height));
+		c.setVWidth(Double.valueOf(width).intValue());
+		c.setVHeight(Double.valueOf(height).intValue());
 		if (interviewPodId > 0) {
 			c.setInterviewPodId(interviewPodId);
 		}
 		sessionManager.updateClientByStreamId(c.getStreamid(), c, false, null);
-		HashMap<String, Object> hsm = new HashMap<String, Object>();
+		Map<String, Object> hsm = new HashMap<>();
 		hsm.put("client", c);
 		hsm.put("message", new String[]{"avsettings", "0", avMode});
-		Map<String, Object> result = new Hashtable<String, Object>();
+		Map<String, Object> result = new Hashtable<>();
 		if (!"n".equals(avMode)) {
 			result.put("broadcastId", nextBroadCastId());
 		}
@@ -362,7 +367,7 @@ public class MobileService {
 		"sendVarsToMessageWithClient"
 	}
 
-	public List<ChatMessageDTO> getRoomChatHistory() {
+	public List<Map<String, Object>> getRoomChatHistory() {
 		try {
 			IConnection current = Red5.getConnectionLocal();
 			Client currentClient = this.sessionManager.getClientByStreamId(current.getClient().getId(), null);
@@ -371,7 +376,7 @@ public class MobileService {
 			log.debug("GET CHATROOM: " + roomId);
 
 			List<Map<String,Object>> myChatList = myChats.get(roomId);
-			if (myChatList==null) myChatList = new LinkedList<Map<String,Object>>();
+			if (myChatList==null) myChatList = new ArrayList<Map<String,Object>>();
 
 			if (!currentClient.getIsMod() && !currentClient.getIsSuperModerator()) {
 				//current user is not moderator, chat history need to be filtered

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/RecordingService.java Thu Feb 16 04:15:27 2017
@@ -30,6 +30,7 @@ import org.apache.openmeetings.core.data
 import org.apache.openmeetings.core.data.record.converter.RecordingConverterTask;
 import org.apache.openmeetings.core.data.record.listener.StreamListener;
 import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.record.RecordingDao;
 import org.apache.openmeetings.db.dao.record.RecordingMetaDataDao;
 import org.apache.openmeetings.db.dao.record.RecordingMetaDeltaDao;
@@ -142,7 +143,7 @@ public class RecordingService implements
 						Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
 
 						// Send every user a notification that the recording did start
-						scopeApplicationAdapter.broadcastRoom(new TextRoomMessage(roomId, ownerId, RoomMessage.Type.recordingStarted, client.getPublicSID()));
+						WebSocketHelper.sendRoom(new TextRoomMessage(roomId, ownerId, RoomMessage.Type.recordingStarted, client.getPublicSID()));
 
 						// If its the recording client we need another type of Meta Data
 						if (rcl.isScreenClient()) {
@@ -310,7 +311,7 @@ public class RecordingService implements
 	public Long stopRecordAndSave(IScope scope, Client client, Long storedRecordingId) {
 		try {
 			log.debug("stopRecordAndSave " + client.getUsername() + "," + client.getUserip());
-			scopeApplicationAdapter.broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.recordingStoped, client.getPublicSID()));
+			WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.recordingStoped, client.getPublicSID()));
 
 			// get all stream and stop recording them
 			for (IConnection conn : scope.getClientConnections()) {

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java Thu Feb 16 04:15:27 2017
@@ -40,6 +40,7 @@ import org.apache.openmeetings.core.data
 import org.apache.openmeetings.core.remote.RecordingService;
 import org.apache.openmeetings.core.remote.WhiteBoardService;
 import org.apache.openmeetings.core.remote.util.SessionVariablesUtil;
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
@@ -59,6 +60,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.server.Server;
+import org.apache.openmeetings.db.entity.server.Sessiondata;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
 import org.apache.openmeetings.util.CalendarPatterns;
@@ -69,9 +71,6 @@ import org.apache.openmeetings.util.Vers
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.util.message.TextRoomMessage;
 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.registry.IWebSocketConnectionRegistry;
 import org.apache.wicket.util.string.StringValue;
 import org.apache.wicket.util.string.Strings;
 import org.red5.logging.Red5LoggerFactory;
@@ -147,11 +146,11 @@ public class ScopeApplicationAdapter ext
 			for (String scopeName : scope.getScopeNames()) {
 				log.debug("scopeName :: " + scopeName);
 			}
-			
+
 			InitializationContainer.initComplete = true;
 			Version.logOMStarted();
 			recordingDao.resetProcessingStatus(); //we are starting so all processing recordings are now errors
-			sessionManager.clearCache(); // 'sticky' clients should be cleaned up from DB 
+			sessionManager.clearCache(); // 'sticky' clients should be cleaned up from DB
 		} catch (Exception err) {
 			log.error("[appStart]", err);
 		}
@@ -161,11 +160,11 @@ public class ScopeApplicationAdapter ext
 	@SuppressWarnings("unchecked")
 	private static Map<String, Object> getConnParams(Object[] params) {
 		if (params != null && params.length > 0) {
-			return (Map<String, Object>)params[0]; 
+			return (Map<String, Object>)params[0];
 		}
 		return new HashMap<>();
 	}
-	
+
 	@Override
 	public boolean roomConnect(IConnection conn, Object[] params) {
 		log.debug("roomConnect : ");
@@ -185,6 +184,9 @@ public class ScopeApplicationAdapter ext
 		String uid = (String)connParams.get("uid");
 		String securityCode = (String)connParams.get(SECURITY_CODE_PARAM);
 		String parentSid = (String)map.get("parentSid");
+		if (parentSid == null) {
+			parentSid = (String)connParams.get("parentSid");
+		}
 		if (!Strings.isEmpty(securityCode)) {
 			//FIXME TODO add better mechanism, this is for external applications like ffmpeg
 			Client parent = sessionManager.getClientByPublicSID(securityCode, null);
@@ -202,10 +204,8 @@ public class ScopeApplicationAdapter ext
 		}
 
 		Client rcm = new Client();
-		Client parentClient = null;
-		//TODO add similar code for other connections
 		if (map.containsKey("screenClient")) {
-			parentClient = sessionManager.getClientByPublicSID(parentSid, null);
+			Client parentClient = sessionManager.getClientByPublicSID(parentSid, null);
 			if (parentClient == null) {
 				log.warn("Bad parent for screen-sharing client, client is rejected");
 				return rejectClient();
@@ -220,12 +220,24 @@ public class ScopeApplicationAdapter ext
 		StringValue scn = StringValue.valueOf(conn.getScope().getName());
 		rcm.setScope(scn.toString());
 		long roomId = scn.toLong(Long.MIN_VALUE);
+		boolean notHibernate = !"hibernate".equals(scn.toString());
 		if (Long.MIN_VALUE != roomId) {
 			rcm.setRoomId(roomId);
-		} else if (!"hibernate".equals(scn.toString())) {
+		} else if (notHibernate) {
 			log.warn("Bad room specified, client is rejected");
 			return rejectClient();
 		}
+		if (connParams.containsKey("mobileClient")) {
+			Sessiondata sd = sessiondataDao.check(parentSid);
+			if (sd.getUserId() == null && notHibernate) {
+				log.warn("Attempt of unauthorized room enter, client is rejected");
+				return rejectClient();
+			}
+			rcm.setMobile(true);
+			rcm.setUserId(sd.getUserId());
+			rcm.setSecurityCode(sd.getSessionId());
+			rcm.setPublicSID(UUID.randomUUID().toString());
+		}
 		rcm.setUserport(conn.getRemotePort());
 		rcm.setUserip(conn.getRemoteAddress());
 		rcm.setSwfurl(swfURL);
@@ -240,7 +252,7 @@ public class ScopeApplicationAdapter ext
 			log.warn("Failed to create Client on room connect");
 			return false;
 		}
-		
+
 		SessionVariablesUtil.initClient(conn.getClient(), rcm.getPublicSID());
 		//TODO add similar code for other connections, merge with above block
 		if (map.containsKey("screenClient")) {
@@ -283,15 +295,15 @@ public class ScopeApplicationAdapter ext
 					client.setStartStreaming(false);
 					//Send message to all users
 					sendMessageToCurrentScope("stopScreenSharingMessage", client, false);
-					broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
-					
+					WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
+
 					returnMap.put("result", "stopSharingOnly");
 				}
 				if (Boolean.parseBoolean("" + map.get("stopRecording")) && client.getIsRecording()) {
 					changed = true;
 					client.setStartRecording(false);
 					client.setIsRecording(false);
-					
+
 					returnMap.put("result", "stopRecordingOnly");
 
 					recordingService.stopRecordAndSave(current.getScope(), client, null);
@@ -300,14 +312,14 @@ public class ScopeApplicationAdapter ext
 					changed = true;
 					client.setScreenPublishStarted(false);
 					returnMap.put("result", "stopPublishingOnly");
-					
+
 					//Send message to all users
 					sendMessageToCurrentScope("stopPublishingMessage", client, false);
 				}
-				
+
 				if (changed) {
 					sessionManager.updateClientByStreamId(client.getStreamid(), client, false, null);
-					
+
 					if (!client.isStartStreaming() && !client.isStartRecording() && !client.isStreamPublishStarted()) {
 						returnMap.put("result", "stopAll");
 					}
@@ -346,10 +358,10 @@ public class ScopeApplicationAdapter ext
 	}
 
 	/**
-	 * 
+	 *
 	 * @param map
 	 * @return returns key,value Map with multiple return values or null in case of exception
-	 * 
+	 *
 	 */
 	public Map<String, Object> setConnectionAsSharingClient(Map<String, Object> map) {
 		try {
@@ -396,12 +408,12 @@ public class ScopeApplicationAdapter ext
 				if (startStreaming) {
 					if (!alreadyStreaming) {
 						returnMap.put("modus", "startStreaming");
-	
+
 						log.debug("start streamPublishStart Is Screen Sharing ");
-						
+
 						//Send message to all users
 						sendMessageToCurrentScope("newScreenSharing", client, false);
-						broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStarted, client.getStreamPublishName()));
+						WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStarted, client.getStreamPublishName()));
 					} else {
 						log.warn("Streaming is already started for the client id=" + client.getId() + ". Second request is ignored.");
 					}
@@ -409,9 +421,9 @@ public class ScopeApplicationAdapter ext
 				if (startRecording) {
 					if (!alreadyRecording) {
 						returnMap.put("modus", "startRecording");
-	
+
 						String recordingName = "Recording " + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date());
-	
+
 						recordingService.recordMeetingStream(current, client, recordingName, "", false);
 					} else {
 						log.warn("Recording is already started for the client id=" + client.getId() + ". Second request is ignored.");
@@ -464,7 +476,7 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * this function is invoked directly after initial connecting
-	 * 
+	 *
 	 * @return publicSID of current client
 	 */
 	public String getPublicSID() {
@@ -477,7 +489,7 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * this function is invoked after a reconnect
-	 * 
+	 *
 	 * @param newPublicSID
 	 */
 	public boolean overwritePublicSID(String newPublicSID) {
@@ -502,7 +514,7 @@ public class ScopeApplicationAdapter ext
 	/**
 	 * Logic must be before roomDisconnect cause otherwise you cannot throw a
 	 * message to each one
-	 * 
+	 *
 	 */
 	@Override
 	public void roomLeave(IClient client, IScope room) {
@@ -525,11 +537,11 @@ public class ScopeApplicationAdapter ext
 	/**
 	 * this means a user has left a room but only logically, he didn't leave the
 	 * app he just left the room
-	 * 
+	 *
 	 * FIXME: Is this really needed anymore if you re-connect to another scope?
-	 * 
+	 *
 	 * Exit Room by Application
-	 * 
+	 *
 	 */
 	public void logicalRoomLeave() {
 		log.debug("logicalRoomLeave ");
@@ -550,10 +562,10 @@ public class ScopeApplicationAdapter ext
 	/**
 	 * Removes the Client from the List, stops recording, adds the Room-Leave
 	 * event to running recordings, clear Polls and removes Client from any list
-	 * 
-	 * This function is kind of private/protected as the client won't be able 
+	 *
+	 * This function is kind of private/protected as the client won't be able
 	 * to call it with proper values.
-	 * 
+	 *
 	 * @param client
 	 * @param scope
 	 */
@@ -561,10 +573,10 @@ public class ScopeApplicationAdapter ext
 		try {
 			log.debug("currentClient " + client);
 			Long roomId = client.getRoomId();
-			
+
 			if (client.isScreenClient() && client.isStartStreaming()) {
 				//TODO check others/find better way
-				broadcastRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
+				WebSocketHelper.sendRoom(new TextRoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.sharingStoped, client.getStreamPublishName()));
 			}
 
 			// Log the User
@@ -613,7 +625,7 @@ public class ScopeApplicationAdapter ext
 							log.debug("For this StreamId: " + cons.getClient().getId() + " There is no Client in the List anymore");
 							continue;
 						}
-						
+
 						//Do not send back to sender, but actually all other clients should receive this message swagner 01.10.2009
 						if (!client.getStreamid().equals(rcl.getStreamid())) {
 							// add Notification if another user isrecording
@@ -622,7 +634,7 @@ public class ScopeApplicationAdapter ext
 								log.debug("*** roomLeave Any Client is Recording - stop that");
 								recordingService.stopRecordingShowForClient(cons, client);
 							}
-							
+
 							boolean isScreen = rcl.isScreenClient();
 							if (isScreen && client.getPublicSID().equals(rcl.getStreamPublishName())) {
 								//going to terminate screen sharing started by this client
@@ -632,7 +644,7 @@ public class ScopeApplicationAdapter ext
 								// screen sharing clients do not receive events
 								continue;
 							}
-							
+
 							// Send to all connected users
 							((IServiceCapableConnection) cons).invoke("roomDisconnect", new Object[] { client },this);
 							log.debug("sending roomDisconnect to " + cons);
@@ -641,6 +653,10 @@ public class ScopeApplicationAdapter ext
 				}
 			}
 
+			if (client.isMobile()) {
+				IApplication app = (IApplication)Application.get(OpenmeetingsVariables.wicketApplicationName);
+				app.exit(client.getPublicSID());
+			}
 			if (removeUserFromSessionList) {
 				sessionManager.removeClient(client.getStreamid(), null);
 			}
@@ -652,7 +668,7 @@ public class ScopeApplicationAdapter ext
 	/**
 	 * This method handles the Event after a stream has been added all connected
 	 * Clients in the same room will get a notification
-	 * 
+	 *
 	 */
 	/* (non-Javadoc)
 	 * @see org.red5.server.adapter.MultiThreadedApplicationAdapter#streamPublishStart(org.red5.server.api.stream.IBroadcastStream)
@@ -665,10 +681,10 @@ public class ScopeApplicationAdapter ext
 			final String streamid = current.getClient().getId();
 			final Client currentClient = sessionManager.getClientByStreamId(streamid, null);
 
-			//We make a second object the has the reference to the object 
+			//We make a second object the has the reference to the object
 			//that we will use to send to all participents
 			Client clientObjectSendToSync = currentClient;
-			
+
 			// Notify all the clients that the stream had been started
 			log.debug("start streamPublishStart broadcast start: " + stream.getPublishedName() + " CONN " + current);
 
@@ -684,7 +700,7 @@ public class ScopeApplicationAdapter ext
 				currentClient.setVHeight(240);
 				sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
 			}
-			
+
 			log.debug("newStream SEND: " + currentClient);
 
 			// Notify all users of the same Scope
@@ -693,14 +709,14 @@ public class ScopeApplicationAdapter ext
 				@Override
 				public boolean filter(IConnection conn) {
 					Client rcl = sessionManager.getClientByStreamId(conn.getClient().getId(), null);
-					
+
 					if (rcl == null) {
 						log.debug("RCL IS NULL newStream SEND");
 						return true;
 					}
-					
+
 					log.debug("check send to "+rcl);
-					
+
 					if (rcl.getPublicSID() == "") {
 						log.debug("publicSID IS NULL newStream SEND");
 						return true;
@@ -713,7 +729,7 @@ public class ScopeApplicationAdapter ext
 						log.debug("RCL getIsScreenClient newStream SEND");
 						return true;
 					}
-					
+
 					if (rcl.getPublicSID().equals(currentClient.getPublicSID())) {
 						log.debug("RCL publicSID is equal newStream SEND");
 						return true;
@@ -739,7 +755,7 @@ public class ScopeApplicationAdapter ext
 	/**
 	 * This method handles the Event after a stream has been removed all
 	 * connected Clients in the same room will get a notification
-	 * 
+	 *
 	 */
 	/* (non-Javadoc)
 	 * @see org.red5.server.adapter.MultiThreadedApplicationAdapter#streamBroadcastClose(org.red5.server.api.stream.IBroadcastStream)
@@ -760,9 +776,9 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * This method handles the notification room-based
-	 * 
+	 *
 	 * @return void
-	 * 
+	 *
 	 */
 	private void sendClientBroadcastNotifications(IBroadcastStream stream, String clientFunction, Client rc) {
 		try {
@@ -917,7 +933,7 @@ public class ScopeApplicationAdapter ext
 	 * cause if the room has no moderator yet there is no-one he can ask to get
 	 * the moderation, in case its a Non-Moderated Room he should then get the
 	 * Moderation without any confirmation needed
-	 * 
+	 *
 	 * @return Long 1 => means get Moderation, 2 => ask Moderator for
 	 *         Moderation, 3 => wait for Moderator
 	 */
@@ -951,9 +967,9 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * This method is used to set/update broadCastID of current client
-	 * 
-	 * @param updateBroadcastId boolean flag 
-	 * 
+	 *
+	 * @param updateBroadcastId boolean flag
+	 *
 	 * @return BroadcastId in case of no errors, -1 otherwise
 	 */
 	public long setUserAVSettings(boolean updateBroadcastId) {
@@ -1011,7 +1027,7 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * This function is called once a User enters a Room
-	 * 
+	 *
 	 * It contains several different mechanism depending on what roomtype and
 	 * what options are available for the room to find out if the current user
 	 * will be a moderator of that room or not<br/>
@@ -1069,7 +1085,7 @@ public class ScopeApplicationAdapter ext
 			conferenceLogDao.add(ConferenceLog.Type.roomEnter,
 					client.getUserId(), streamid, roomId,
 					client.getUserip(), "");
-			
+
 			// Check for Moderation LogicalRoom ENTER
 			List<Client> roomClients = sessionManager.getClientListByRoom(roomId);
 
@@ -1090,11 +1106,11 @@ public class ScopeApplicationAdapter ext
 				sessionManager.updateClientByStreamId(streamid, client, false, null);
 
 				List<Client> modRoomList = sessionManager.getCurrentModeratorByRoom(client.getRoomId());
-				
+
 				//Sync message to everybody
 				sendMessageToCurrentScope("setNewModeratorByList", modRoomList, false);
 			}
-			
+
 			//Sync message to everybody
 			sendMessageToCurrentScope("addNewUser", client, false);
 
@@ -1119,57 +1135,8 @@ public class ScopeApplicationAdapter ext
 	}
 
 	/**
-	 * This method is invoked when the user has disconnected and reconnects to
-	 * the Gateway with the new scope
-	 * 
-	 * @param SID
-	 * @param userId
-	 * @param username
-	 * @param firstname
-	 * @param lastname
-	 * @param picture_uri
-	 * @return client being updated in case of success, null otherwise
-	 */
-	public Client setUsernameReconnect(String SID, Long userId, String username, String firstname, String lastname, String picture_uri) {
-		try {
-			log.debug("-----------  setUsernameReconnect");
-			IConnection current = Red5.getConnectionLocal();
-			String streamid = current.getClient().getId();
-			Client currentClient = sessionManager.getClientByStreamId(streamid, null);
-
-			SessionVariablesUtil.setUserId(current.getClient(), userId);
-			currentClient.setPicture_uri(picture_uri);
-			currentClient.setUserObject(userId, username, firstname, lastname);
-
-			// Update Session Data
-			sessiondataDao.updateUserWithoutSession(SID, userId);
-
-			// only fill this value from User-Record
-			// cause invited users have no associated User, so
-			// you cannot set the firstname,lastname from the UserRecord
-			if (userId != null) {
-				User us = userDao.get(userId);
-				
-				if (us != null) {
-					currentClient.setExternalUserId(us.getExternalId());
-					currentClient.setExternalUserType(us.getExternalType());
-					if (us.getPictureuri() != null) {
-						// set Picture-URI
-						currentClient.setPicture_uri(us.getPictureuri());
-					}
-				}
-			}
-			sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-			return currentClient;
-		} catch (Exception err) {
-			log.error("[setUsername]", err);
-		}
-		return null;
-	}
-
-	/**
 	 * this is set initial directly after login/loading language
-	 * 
+	 *
 	 * @param SID - id of the session
 	 * @param userId - id of the user being set
 	 * @param username - username of the user
@@ -1218,7 +1185,7 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * used by the Screen-Sharing Servlet to trigger events
-	 * 
+	 *
 	 * @param roomId
 	 * @param message
 	 * @return the list of room clients
@@ -1261,7 +1228,7 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * This Function is triggered from the Whiteboard
-	 * 
+	 *
 	 * @param whiteboardObjParam - array of parameters being sended to whiteboard
 	 * @param whiteboardId - id of whiteboard parameters will be send to
 	 * @return 1 in case of no errors, -1 otherwise
@@ -1276,7 +1243,7 @@ public class ScopeApplicationAdapter ext
 			return -1;
 		}
 	}
-	
+
 	private static Point getSize(FileItem fi) {
 		Point result = new Point(0, 0);
 		if (fi.getFlvWidth() != null && fi.getFlvHeight() != null) {
@@ -1285,7 +1252,7 @@ public class ScopeApplicationAdapter ext
 		}
 		return result;
 	}
-	
+
 	private static List<?> getWbObject(FileItem fi, String url) {
 		String fuid = UUID.randomUUID().toString();
 		Point size = getSize(fi);
@@ -1330,7 +1297,7 @@ public class ScopeApplicationAdapter ext
 				, fuid // this.currentlayer.name //-1
 				);
 	}
-	
+
 	private static List<?> getFlvWbObject(FileItem fi) {
 		String fuid = UUID.randomUUID().toString();
 		Point size = getSize(fi);
@@ -1341,17 +1308,17 @@ public class ScopeApplicationAdapter ext
 				, false // 3: false //playRemote
 				, size.x // 4: 416
 				, size.y // 5: 240
-				, 0 // 6: 1 // z-index 
-				, fi.getHash() // 7: null //TODO 
+				, 0 // 6: 1 // z-index
+				, fi.getHash() // 7: null //TODO
 				, 0 // 8: 0 //TODO // counter
 				, 0 // 9: 0 //TODO // x
 				, 0 // 10: 0 //TODO // y
 				, size.x // 11: 749 // width
 				, size.y // 12: 739 // height
-				, fuid // 13: 'flv_1469602000351' 
+				, fuid // 13: 'flv_1469602000351'
 				);
 	}
-	
+
 	public void sendToWhiteboard(String uid, Long wbId, FileItem fi, String url, boolean clean) {
 		ClientSessionInfo csi = sessionManager.getClientByPublicSIDAnyServer(uid);
 		if (csi == null) {
@@ -1359,7 +1326,7 @@ public class ScopeApplicationAdapter ext
 			return;
 		}
 		Client client = csi.getRcl();
-		
+
 		List<?> wbObject = new ArrayList<>();
 		switch (fi.getType()) {
 			case Image:
@@ -1382,14 +1349,14 @@ public class ScopeApplicationAdapter ext
 		}
 		sendToWhiteboard(client, Arrays.asList("whiteboard", new Date(), "draw", wbObject), wbId);
 	}
-	
+
 	private int sendToWhiteboard(Client client, List<?> wbObj, Long wbId) {
 		try {
 			// Check if this User is the Mod:
 			if (client == null) {
 				return -1;
 			}
-			
+
 			Map<Integer, Object> whiteboardObj = new HashMap<>();
 			int i = 0;
 			for (Object obj : wbObj) {
@@ -1451,7 +1418,7 @@ public class ScopeApplicationAdapter ext
 		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
 		return 1;
 	}
-	
+
 	public int sendMessageAll(Object newMessage) {
 		sendMessageToCurrentScope("sendVarsToMessage", newMessage, true);
 		return 1;
@@ -1485,7 +1452,7 @@ public class ScopeApplicationAdapter ext
 			}
 
 			current.getScope().setAttribute("browserStatus", browserStatus);
-			
+
 			sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
 
 		} catch (Exception err) {
@@ -1502,9 +1469,9 @@ public class ScopeApplicationAdapter ext
 		//Sync to all users of current scope
 		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
 	}
-	
+
 	/**
-	 * General sync mechanism for all messages that are send from within the 
+	 * General sync mechanism for all messages that are send from within the
 	 * scope of the current client, but:
 	 * <ul>
 	 * <li>optionally do not send to self (see param: sendSelf)</li>
@@ -1512,7 +1479,7 @@ public class ScopeApplicationAdapter ext
 	 * <li>do not send to clients that are audio/video clients (or potentially ones)</li>
 	 * <li>do not send to connections where no RoomClient is registered</li>
 	 * </ul>
-	 *  
+	 *
 	 * @param remoteMethodName The method to be called
 	 * @param newMessage parameters
 	 * @param sendSelf send to the current client as well
@@ -1520,7 +1487,7 @@ public class ScopeApplicationAdapter ext
 	public void sendMessageToCurrentScope(String remoteMethodName, Object newMessage, boolean sendSelf) {
 		sendMessageToCurrentScope(remoteMethodName, newMessage, sendSelf, false);
 	}
-	
+
 	public void sendToScope(final Long roomId, String method, Object obj) {
 		new MessageSender(getRoomScope("" + roomId), method, obj) {
 			@Override
@@ -1531,10 +1498,10 @@ public class ScopeApplicationAdapter ext
 			}
 		}.start();
 	}
-	
+
 	/**
 	 * Only temporary for load test, with return argument for the client to have a result
-	 * 
+	 *
 	 * @param remoteMethodName
 	 * @param newMessage
 	 * @param sendSelf
@@ -1545,10 +1512,9 @@ public class ScopeApplicationAdapter ext
 		sendMessageToCurrentScope(remoteMethodName, newMessage, sendSelf, false);
 		return true;
 	}
-	
-	
+
 	/**
-	 * General sync mechanism for all messages that are send from within the 
+	 * General sync mechanism for all messages that are send from within the
 	 * scope of the current client, but:
 	 * <ul>
 	 * <li>optionally do not send to self (see param: sendSelf)</li>
@@ -1556,7 +1522,7 @@ public class ScopeApplicationAdapter ext
 	 * <li>do not send to clients that are audio/video clients (or potentially ones)</li>
 	 * <li>do not send to connections where no RoomClient is registered</li>
 	 * </ul>
-	 *  
+	 *
 	 * @param remoteMethodName The method to be called
 	 * @param newMessage parameters
 	 * @param sendSelf send to the current client as well
@@ -1578,28 +1544,28 @@ public class ScopeApplicationAdapter ext
 		final IConnection current;
 		final String remoteMethodName;
 		final Object newMessage;
-		
+
 		public MessageSender(final String remoteMethodName, final Object newMessage) {
 			this((IScope)null, remoteMethodName, newMessage);
 		}
-		
+
 		public MessageSender(IScope _scope, String remoteMethodName, Object newMessage) {
 			this(Red5.getConnectionLocal(), _scope, remoteMethodName, newMessage);
 		}
-		
+
 		public MessageSender(IConnection current, String remoteMethodName, Object newMessage) {
 			this(current, null, remoteMethodName, newMessage);
 		}
-		
+
 		public MessageSender(IConnection current, IScope _scope, String remoteMethodName, Object newMessage) {
 			this.current = current;
 			scope = _scope == null ? current.getScope() : _scope;
 			this.remoteMethodName = remoteMethodName;
 			this.newMessage = newMessage;
 		}
-		
+
 		public abstract boolean filter(IConnection conn);
-		
+
 		@Override
 		public void run() {
 			try {
@@ -1645,7 +1611,7 @@ public class ScopeApplicationAdapter ext
 		}
 		return 1;
 	}
-	
+
 	/**
 	 * wrapper method
 	 * @param newMessage
@@ -1660,7 +1626,7 @@ public class ScopeApplicationAdapter ext
 			HashMap<String, Object> hsm = new HashMap<String, Object>();
 			hsm.put("client", currentClient);
 			hsm.put("message", newMessage);
-			
+
 			//Sync to all users of current scope
 			sendMessageToCurrentScope("sendVarsToMessageWithClient", hsm, sync);
 
@@ -1672,9 +1638,9 @@ public class ScopeApplicationAdapter ext
 	}
 
 	/**
-	 * Function is used to send the kick Trigger at the moment, 
+	 * Function is used to send the kick Trigger at the moment,
 	 * it sends a general message to a specific clientId
-	 * 
+	 *
 	 * @param newMessage
 	 * @param clientId
 	 * @return 1 in case of success, -1 otherwise
@@ -1705,7 +1671,7 @@ public class ScopeApplicationAdapter ext
 
 	/**
 	 * Sends a message to a user in the same room by its clientId
-	 * 
+	 *
 	 * @param newMessage
 	 * @param clientId
 	 * @return 1 in case of no exceptions, -1 otherwise
@@ -1731,7 +1697,7 @@ public class ScopeApplicationAdapter ext
 		}
 		return 1;
 	}
-	
+
 	public void sendMessageWithClientByPublicSID(Object message, String publicSID) {
 		try {
 			if (publicSID == null) {
@@ -1758,7 +1724,7 @@ public class ScopeApplicationAdapter ext
 						// screen sharing clients do not receive events
 						continue;
 					}
-					
+
 					if (publicSID.equals(SessionVariablesUtil.getPublicSID(client))) {
 						((IServiceCapableConnection) conn).invoke("newMessageByRoomAndDomain", new Object[] { message }, this);
 					}
@@ -1777,6 +1743,7 @@ public class ScopeApplicationAdapter ext
 	 *             recording instead of iterating through connections!
 	 * @return true in case there is recording session, false otherwise, null if any exception happend
 	 */
+	@Deprecated
 	public boolean getInterviewRecordingStatus() {
 		try {
 			IConnection current = Red5.getConnectionLocal();
@@ -1800,6 +1767,7 @@ public class ScopeApplicationAdapter ext
 	 * @deprecated @see {@link ScopeApplicationAdapter#getInterviewRecordingStatus()}
 	 * @return - false if there were existing recording, true if recording was started successfully, null if any exception happens
 	 */
+	@Deprecated
 	public boolean startInterviewRecording() {
 		try {
 			log.debug("-----------  startInterviewRecording");
@@ -1850,7 +1818,7 @@ public class ScopeApplicationAdapter ext
 	@SuppressWarnings({ "rawtypes" })
 	public boolean sendRemoteCursorEvent(final String streamid, Map messageObj) {
 		new MessageSender("sendRemoteCursorEvent", messageObj) {
-			
+
 			@Override
 			public boolean filter(IConnection conn) {
 				IClient client = conn.getClient();
@@ -1876,10 +1844,10 @@ public class ScopeApplicationAdapter ext
 		}
 		return recordingId;
 	}
-	
+
 	/**
 	 * Stop the recording of the streams and send event to connected users of scope
-	 * 
+	 *
 	 * @return true if interview was found
 	 */
 	public boolean stopInterviewRecording() {
@@ -1887,10 +1855,10 @@ public class ScopeApplicationAdapter ext
 		Client currentClient = sessionManager.getClientByStreamId(current.getClient().getId(), null);
 		return _stopInterviewRecording(currentClient, current.getScope());
 	}
-	
+
 	/**
 	 * Stop the recording of the streams and send event to connected users of scope
-	 * 
+	 *
 	 * @return true if interview was found
 	 */
 	private boolean _stopInterviewRecording(Client currentClient, IScope currentScope) {
@@ -1926,7 +1894,7 @@ public class ScopeApplicationAdapter ext
 	/**
 	 * Get all ClientList Objects of that room and domain Used in
 	 * lz.applyForModeration.lzx
-	 * 
+	 *
 	 * @return all ClientList Objects of that room
 	 */
 	public List<Client> getClientListScope() {
@@ -1944,7 +1912,7 @@ public class ScopeApplicationAdapter ext
 	private boolean getWhiteboardDrawStatus() {
 		return configurationDao.getWhiteboardDrawStatus();
 	}
-	
+
 	public String getCryptKey() {
 		return configurationDao.getCryptKey();
 	}
@@ -1976,7 +1944,7 @@ public class ScopeApplicationAdapter ext
 		}
 		return result.isEmpty() ? result : roomDao.getSipRooms(result);
 	}
-	
+
 	public List<Long> getActiveRoomIds() {
 		List<Long> result = getVerifiedActiveRoomIds(null);
 		for (Server s : serverDao.getActiveServers()) {
@@ -1984,15 +1952,15 @@ public class ScopeApplicationAdapter ext
 		}
 		return result.isEmpty() ? result : roomDao.getSipRooms(result);
 	}
-	
+
 	private String getSipTransportLastname(Long roomId) {
 		return getSipTransportLastname(roomManager.getSipConferenceMembersNumber(roomId));
 	}
-	
+
 	private static String getSipTransportLastname(Integer c) {
 		return (c != null && c > 0) ? "(" + (c - 1) + ")" : "";
 	}
-	
+
 	public synchronized int updateSipTransport() {
 		log.debug("-----------  updateSipTransport");
 		IConnection current = Red5.getConnectionLocal();
@@ -2035,16 +2003,4 @@ public class ScopeApplicationAdapter ext
 
 		sendMessageToCurrentScope("addNewUser", currentClient, false);
 	}
-	
-	public void broadcastRoom(RoomMessage msg) {
-		log.debug("Sending WebSocket message: {} {}", msg.getType(), msg instanceof TextRoomMessage ? ((TextRoomMessage)msg).getText() : "");
-		Application app = Application.get(OpenmeetingsVariables.wicketApplicationName);
-		WebSocketSettings settings = WebSocketSettings.Holder.get(app);
-		IWebSocketConnectionRegistry registry = settings.getConnectionRegistry();
-		for (IWebSocketConnection wc : registry.getConnections(app)) {
-			if (wc != null && wc.isOpen()) {
-				wc.sendMessage(msg);
-			}
-		}
-	}
 }

Modified: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/session/SessionManager.java Thu Feb 16 04:15:27 2017
@@ -42,25 +42,25 @@ import org.springframework.beans.factory
 
 /**
  * Handle {@link Client} objects.
- * 
+ *
  * Use a kind of decorator pattern to inject the {@link Server} into every call.
- * 
+ *
  * @author sebawagner
- * 
+ *
  */
 public class SessionManager implements ISessionManager {
 	protected static final Logger log = Red5LoggerFactory.getLogger(SessionManager.class, webAppRootKey);
-	
+
 	@Autowired
 	private ServerUtil serverUtil;
-	
+
 	/**
 	 * Injected via Spring, needs a getter/setter because it can be configured
 	 * Autowired will not suit here as there are multiple implementations of the
 	 * {@link IClientPersistenceStore}
 	 */
 	private IClientPersistenceStore cache;
-	
+
 	public IClientPersistenceStore getCache() {
 		return cache;
 	}
@@ -73,9 +73,12 @@ public class SessionManager implements I
 	public void clearCache() {
 		cache.clear();
 	}
-	
+
 	@Override
 	public Client add(Client c, Server server) {
+		if (c == null) {
+			return null;
+		}
 		if (server == null) {
 			server = serverUtil.getCurrentServer();
 		}
@@ -94,7 +97,7 @@ public class SessionManager implements I
 		cache.put(c.getStreamid(), c);
 		return c;
 	}
-	
+
 	@Override
 	public Client addClientListItem(String streamId, String scopeName,
 			int remotePort, String remoteAddress, String swfUrl, Server server) {
@@ -134,7 +137,7 @@ public class SessionManager implements I
 	public Collection<Client> getClients() {
 		return cache.getClients();
 	}
-	
+
 	@Override
 	public Collection<Client> getClientsWithServer() {
 		return cache.getClientsWithServer();
@@ -192,7 +195,7 @@ public class SessionManager implements I
 				if (rcl.isScreenClient()) {
 					continue;
 				}
-				
+
 				return rcl;
 			}
 		} catch (Exception err) {
@@ -239,7 +242,7 @@ public class SessionManager implements I
 		}
 		try {
 			Client rclSaved = cache.get(server, streamId);
-			
+
 			if (rclSaved != null) {
 				cache.put(streamId, rcm);
 				return true;

Added: openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java?rev=1783168&view=auto
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java (added)
+++ openmeetings/application/branches/3.2.x/openmeetings-core/src/main/java/org/apache/openmeetings/core/util/WebSocketHelper.java Thu Feb 16 04:15:27 2017
@@ -0,0 +1,128 @@
+/*
+ * 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.openmeetings.core.util;
+
+import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import org.apache.openmeetings.IApplication;
+import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.util.OpenmeetingsVariables;
+import org.apache.openmeetings.util.message.RoomMessage;
+import org.apache.openmeetings.util.message.TextRoomMessage;
+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.registry.IWebSocketConnectionRegistry;
+import org.apache.wicket.protocol.ws.api.registry.PageIdKey;
+import org.apache.wicket.protocol.ws.concurrent.Executor;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+
+public class WebSocketHelper {
+	private static final Logger log = Red5LoggerFactory.getLogger(WebSocketHelper.class, webAppRootKey);
+
+	public static void sendClient(final Client c, byte[] b) {
+		if (c != null) {
+			send(a -> Arrays.asList(c), (t) -> {
+				try {
+					t.sendMessage(b, 0, b.length);
+				} catch (IOException e) {
+					log.error("Error while broadcasting byte[] to room", e);
+				}
+			}, null);
+		}
+	}
+
+	public static void sendRoom(final RoomMessage m) {
+		log.debug("Sending WebSocket message: {} {}", m.getType(), m instanceof TextRoomMessage ? ((TextRoomMessage)m).getText() : "");
+		sendRoom(m.getRoomId(), (t) -> t.sendMessage(m), null);
+	}
+
+	public static void sendRoom(final Long roomId, final String m) {
+		sendRoom(roomId, m, null);
+	}
+
+	public static void sendRoom(final Long roomId, final String m, Predicate<Client> check) {
+		log.debug("Sending WebSocket message: {}", m);
+		sendRoom(roomId, (t) -> {
+			try {
+				t.sendMessage(m);
+			} catch (IOException e) {
+				log.error("Error while broadcasting message to room", e);
+			}
+		}, check);
+	}
+
+	public static void sendUser(final Long userId, final String m) {
+		send(a -> ((IApplication)a).getOmClients(userId), (t) -> {
+			try {
+				t.sendMessage(m);
+			} catch (IOException e) {
+				log.error("Error while sending message to user", e);
+			}
+		}, null);
+	}
+
+	//TODO should this be unified???
+	public static void sendAll(final String m) {
+		Application app = Application.get(OpenmeetingsVariables.wicketApplicationName);
+		WebSocketSettings settings = WebSocketSettings.Holder.get(app);
+		IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
+		Executor executor = settings.getWebSocketPushMessageExecutor();
+		for (IWebSocketConnection c : reg.getConnections(app)) {
+			executor.run(() -> {
+				try {
+					c.sendMessage(m);
+				} catch (IOException e) {
+					log.error("Error while sending message to ALL", e);
+				}
+			});
+		}
+	}
+
+	public static void sendRoom(final Long roomId, Consumer<IWebSocketConnection> consumer, Predicate<Client> check) {
+		send(a -> ((IApplication)a).getOmRoomClients(roomId), consumer, check);
+	}
+
+	public static void send(
+			final Function<Application, List<Client>> func
+			, Consumer<IWebSocketConnection> consumer
+			, Predicate<Client> check)
+	{
+		Application app = Application.get(OpenmeetingsVariables.wicketApplicationName);
+		WebSocketSettings settings = WebSocketSettings.Holder.get(app);
+		IWebSocketConnectionRegistry reg = settings.getConnectionRegistry();
+		Executor executor = settings.getWebSocketPushMessageExecutor();
+		for (Client c : func.apply(app)) {
+			if (check == null || (check != null && check.test(c))) {
+				final IWebSocketConnection wc = reg.getConnection(app, c.getSessionId(), new PageIdKey(c.getPageId()));
+				if (wc != null && wc.isOpen()) {
+					executor.run(() -> consumer.accept(wc));
+				}
+			}
+		}
+	}
+}

Modified: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java Thu Feb 16 04:15:27 2017
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings;
 
+import java.util.List;
 import java.util.Locale;
 import java.util.function.Supplier;
 
@@ -39,8 +40,11 @@ public interface IApplication {
 	String getOmString(String key, long languageId);
 	String getOmString(String key, final Locale loc, String... params);
 	Client updateClient(Client rcl);
+	List<org.apache.openmeetings.db.entity.basic.Client> getOmRoomClients(Long roomId);
+	List<org.apache.openmeetings.db.entity.basic.Client> getOmClients(Long userId);
 	String getOmContactsLink();
 	String getOmInvitationLink(Invitation i);
 	String urlForActivatePage(PageParameters pp);
 	void invalidateClient(Long userId, String sessionId);
+	void exit(String uid);
 }

Copied: openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java (from r1783167, openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java)
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java?p2=openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java&p1=openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java&r1=1783167&r2=1783168&rev=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/basic/Client.java Thu Feb 16 04:15:27 2017
@@ -16,9 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.openmeetings.web.app;
-
-import static org.apache.openmeetings.web.app.Application.getBean;
+package org.apache.openmeetings.db.entity.basic;
 
 import java.util.Date;
 import java.util.HashSet;
@@ -66,18 +64,27 @@ public class Client implements IDataProv
 	private int width = 0;
 	private int height = 0;
 
-	public Client(String sessionId, Long userId) {
-		this(sessionId, 0, userId);
+	public Client(String sessionId, Long userId, UserDao dao) {
+		this(sessionId, 0, userId, dao);
 	}
 
-	public Client(String sessionId, int pageId, Long userId) {
+	public Client(String sessionId, int pageId, Long userId, UserDao dao) {
 		this.sessionId = sessionId;
 		this.pageId = pageId;
-		this.user = getBean(UserDao.class).get(userId);
+		this.user = dao.get(userId);
 		this.connectedSince = new Date();
 		uid = UUID.randomUUID().toString();
 	}
 
+	public Client(org.apache.openmeetings.db.entity.room.Client rcl, UserDao dao) {
+		this.sessionId = UUID.randomUUID().toString();
+		this.pageId = 0;
+		this.user = dao.get(rcl.getUserId());
+		this.connectedSince = new Date();
+		uid = rcl.getPublicSID();
+		this.roomId = rcl.getRoomId();
+	}
+
 	public String getSessionId() {
 		return sessionId;
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/hibernate/hibRtmpConnection.lzx Thu Feb 16 04:15:27 2017
@@ -61,7 +61,6 @@
 	<!-- reconnect after each conferenceView -->
 	<attribute name="reconnectedRoomInstance" value="null" />
 
-	<attribute name="reconnectionAction" value="false" type="boolean" />
 	<attribute name="reconnectObjRef" value="null" />
 
 	 <attribute name="userobject" value="null" />
@@ -139,12 +138,7 @@
 	  -->
 	 <handler name="onconnect">
 		if($debug) Debug.write("hibRtmpConnection/onconnect");
-		if (this.reconnectionAction){
-			if (!!canvas.wicketsid) {
-				canvas.sessionId = canvas.wicketsid;
-				getDefaultLanguage.doCall();
-			}
-		} else if (!!canvas.wicketsid) {
+		if (!!canvas.wicketsid) {
 			canvas.sessionId = canvas.wicketsid;
 			if (canvas.thishib.loaderVar != null) {
 				canvas.thishib.loaderVar.setProgress();
@@ -190,17 +184,10 @@
 		connected = false;
 	</handler>
 
-	<method name="reconnectComplete">
-		if (this.reconnectionAction){
-			this.reconnectionAction = false;
-		}
-		canvas.currentContentView.sendInit.sendEvent(this);
-	</method>
-
 	<handler name="onerror" >
 	<![CDATA[
 		canvas.remoteLogWrite("error status='" + this.status + "'; src='" + this.src + "'; lastCalled='" + this.lastCalled
-			+ "'; showKickMessage='" + this.showKickMessage + "'; reconnectionAction='" + this.reconnectionAction + "'");
+			+ "'; showKickMessage='" + this.showKickMessage + "'; ");
 		if (this.showKickMessage) {
 			new lz.labelerrorPopup(canvas,{
 				errorlabelid:606
@@ -210,9 +197,6 @@
 			});
 			canvas._loadingAll.hideContentOnly();
 			return;
-		} else if (this.reconnectionAction){
-			if ($debug) Debug.write("this.reconnectionAction: ", this.lastCalled);
-			this.connect();
 		} else {
 			this.useRTMPT = true
 			var src = getUrl();
@@ -283,20 +267,6 @@
 		]]>
 	</method>
 
-	<netRemoteCallHib name="setUsernameReconnect" funcname="setUsernameReconnect" remotecontext="$once{ canvas.thishib }" >
-		<netparam><method name="getValue">return canvas.sessionId;</method></netparam>
-		<netparam><method name="getValue">return canvas.userId;</method></netparam>
-		<netparam><method name="getValue">return canvas.currentuser;</method></netparam>
-		<netparam><method name="getValue">return canvas.firstName;</method></netparam>
-		<netparam><method name="getValue">return canvas.lastName;</method></netparam>
-		<netparam><method name="getValue">return canvas.picture_uri;</method></netparam>
-		<handler name="ondata" args="value">
-			//The onResult-Handler will be called be the rtmpconnection
-			if ($debug) Debug.write("setUsernameReconnect: ",canvas.userId,value);
-			parent.reconnectComplete();
-		</handler>
-	</netRemoteCallHib>
-
 	<netRemoteCallHib name="getDefaultLanguage" funcname="languageservice.getDefaultLanguage" >
 		<handler name="ondata" args="value">
 			//The onResult-Handler will be called be the rtmpconnection

Modified: openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/mainMethods.lzx
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/mainMethods.lzx?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/mainMethods.lzx (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-flash/src/main/swf/base/mainMethods.lzx Thu Feb 16 04:15:27 2017
@@ -240,7 +240,6 @@
 
 	<method name="quit">
 		canvas.thishib.src = null;
-		canvas.thishib.reconnectionAction = false;
 		canvas.thishib.counterror = 100;
 		canvas.thishib.disconnect();
 		if (canvas.thishib._nc) {

Modified: openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-util/src/main/java/org/apache/openmeetings/util/message/RoomMessage.java Thu Feb 16 04:15:27 2017
@@ -60,7 +60,7 @@ public class RoomMessage implements IWeb
 		this.type = type;
 		this.uid = UUID.randomUUID().toString();
 	}
-	
+
 	public Date getTimestamp() {
 		return timestamp;
 	}

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java Thu Feb 16 04:15:27 2017
@@ -127,12 +127,12 @@ public class ConnectionsPanel extends Ad
 		};
 		add(container.add(dataView).setOutputMarkupId(true), details.setVisible(false).setOutputMarkupPlaceholderTag(true));
 		
-		SearchableDataProvider<org.apache.openmeetings.web.app.Client> sdpWeb = new SearchableDataProvider<org.apache.openmeetings.web.app.Client>(null) {
+		SearchableDataProvider<org.apache.openmeetings.db.entity.basic.Client> sdpWeb = new SearchableDataProvider<org.apache.openmeetings.db.entity.basic.Client>(null) {
 			private static final long serialVersionUID = 1L;
 			
 			@Override
-			public Iterator<? extends org.apache.openmeetings.web.app.Client> iterator(long first, long count) {
-				List<org.apache.openmeetings.web.app.Client> l = new ArrayList<org.apache.openmeetings.web.app.Client>(Application.getClients());
+			public Iterator<? extends org.apache.openmeetings.db.entity.basic.Client> iterator(long first, long count) {
+				List<org.apache.openmeetings.db.entity.basic.Client> l = new ArrayList<org.apache.openmeetings.db.entity.basic.Client>(Application.getClients());
 				return l.subList((int)Math.max(0, first), (int)Math.min(first + count, l.size())).iterator();
 			}
 			
@@ -143,12 +143,12 @@ public class ConnectionsPanel extends Ad
 		};
 		
 		final WebMarkupContainer containerWeb = new WebMarkupContainer("containerWeb");
-		SearchableDataView<org.apache.openmeetings.web.app.Client> dataViewWeb = new SearchableDataView<org.apache.openmeetings.web.app.Client>("clientListWeb", sdpWeb) {
+		SearchableDataView<org.apache.openmeetings.db.entity.basic.Client> dataViewWeb = new SearchableDataView<org.apache.openmeetings.db.entity.basic.Client>("clientListWeb", sdpWeb) {
 			private static final long serialVersionUID = 1L;
 
 			@Override
-			protected void populateItem(final Item<org.apache.openmeetings.web.app.Client> item) {
-				org.apache.openmeetings.web.app.Client c = item.getModelObject();
+			protected void populateItem(final Item<org.apache.openmeetings.db.entity.basic.Client> item) {
+				org.apache.openmeetings.db.entity.basic.Client c = item.getModelObject();
 				item.add(new Label("id", ""));
 				item.add(new Label("login", c.getUser().getLogin()));
 				item.add(new Label("since", c.getConnectedSince()));
@@ -158,7 +158,7 @@ public class ConnectionsPanel extends Ad
 
 					@Override
 					protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
-						org.apache.openmeetings.web.app.Client c = item.getModelObject();
+						org.apache.openmeetings.db.entity.basic.Client c = item.getModelObject();
 						getBean(IUserService.class).kickUserBySessionId(getSid(), c.getUserId(), c.getSessionId());
 						target.add(containerWeb, details.setVisible(false));
 					}
@@ -168,9 +168,9 @@ public class ConnectionsPanel extends Ad
 
 					@Override
 					protected void onEvent(AjaxRequestTarget target) {
-						Field[] ff = org.apache.openmeetings.web.app.Client.class.getDeclaredFields();
+						Field[] ff = org.apache.openmeetings.db.entity.basic.Client.class.getDeclaredFields();
 						RepeatingView lines = new RepeatingView("line");
-						org.apache.openmeetings.web.app.Client c = item.getModelObject();
+						org.apache.openmeetings.db.entity.basic.Client c = item.getModelObject();
 						for (Field f : ff) {
 							int mod = f.getModifiers();
 							if (Modifier.isStatic(mod) || Modifier.isTransient(mod)) {

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Thu Feb 16 04:15:27 2017
@@ -18,6 +18,7 @@
  */
 package org.apache.openmeetings.web.app;
 
+import static org.apache.openmeetings.core.util.WebSocketHelper.sendRoom;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.wicketApplicationName;
 import static org.apache.openmeetings.web.pages.HashPage.INVITATION_HASH;
@@ -40,9 +41,13 @@ import java.util.concurrent.ConcurrentHa
 import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.remote.MainService;
 import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.basic.Client;
+import org.apache.openmeetings.db.entity.basic.Client.Activity;
+import org.apache.openmeetings.db.entity.basic.Client.Pod;
 import org.apache.openmeetings.db.entity.record.Recording;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Room;
@@ -50,8 +55,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.util.InitializationContainer;
-import org.apache.openmeetings.web.app.Client.Activity;
-import org.apache.openmeetings.web.app.Client.Pod;
+import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.web.pages.AccessDeniedPage;
 import org.apache.openmeetings.web.pages.ActivatePage;
 import org.apache.openmeetings.web.pages.HashPage;
@@ -215,8 +219,26 @@ public class Application extends Authent
 		ONLINE_USERS.put(c.getUid(), c);
 	}
 
-	public static void removeOnlineUser(Client c) {
+	public static void exitRoom(Client c) {
+		Long roomId = c.getRoomId();
+		removeUserFromRoom(c);
+		if (roomId != null) {
+			sendRoom(new RoomMessage(roomId, c.getUserId(), RoomMessage.Type.roomExit));
+		}
+	}
+
+	@Override
+	public void exit(String uid) {
+		if (uid != null) {
+			exit(ONLINE_USERS.get(uid));
+		}
+	}
+
+	public static void exit(Client c) {
 		if (c != null) {
+			if (c.getRoomId() != null) {
+				exitRoom(c);
+			}
 			log.debug("Removing online client: {}, room: {}", c.getUid(), c.getRoomId());
 			ONLINE_USERS.remove(c.getUid());
 		}
@@ -227,10 +249,22 @@ public class Application extends Authent
 		if (rcl == null) {
 			return null;
 		}
-		if (!rcl.isScreenClient()) {
+		if (!rcl.isScreenClient() && (!rcl.isMobile() || (rcl.isMobile() && rcl.getUserId() != null))) {
 			Client client = getOnlineClient(rcl.getPublicSID());
 			if (client == null) {
-				return null;
+				if (rcl.isMobile()) {
+					//Mobile client enters the room
+					client = new Client(rcl, getBean(UserDao.class));
+					addOnlineUser(client);
+					if (rcl.getRoomId() != null) {
+						addUserToRoom(client);
+						//FIXME TODO unify this
+						WebSocketHelper.sendRoom(new RoomMessage(client.getRoomId(), client.getUserId(), RoomMessage.Type.roomEnter));
+					}
+					//FIXME TODO rights
+				} else {
+					return null;
+				}
 			}
 			rcl.setIsSuperModerator(client.hasRight(Right.superModerator));
 			rcl.setIsMod(client.hasRight(Right.moderator));
@@ -315,7 +349,7 @@ public class Application extends Authent
 		if (client != null) {
 			if (!INVALID_SESSIONS.containsKey(client.getSessionId())) {
 				INVALID_SESSIONS.put(client.getSessionId(), client);
-				removeOnlineUser(client);
+				exit(client);
 			}
 		}
 	}
@@ -351,6 +385,16 @@ public class Application extends Authent
 		return c;
 	}
 
+	@Override
+	public List<Client> getOmRoomClients(Long roomId) {
+		return getRoomClients(roomId);
+	}
+
+	@Override
+	public List<Client> getOmClients(Long userId) {
+		return getClients(userId);
+	}
+
 	public static List<Client> getRoomClients(Long roomId) {
 		List<Client> clients = new ArrayList<>();
 		if (roomId != null) {

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java Thu Feb 16 04:15:27 2017
@@ -24,13 +24,13 @@ import static org.apache.openmeetings.ut
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DASHBOARD_SHOW_RSS_KEY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_LANG_KEY;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.web.app.Application.exit;
 import static org.apache.openmeetings.web.app.Application.getAuthenticationStrategy;
 import static org.apache.openmeetings.web.app.Application.getBean;
 import static org.apache.openmeetings.web.app.Application.getClientByKeys;
 import static org.apache.openmeetings.web.app.Application.getDashboardContext;
 import static org.apache.openmeetings.web.app.Application.isInvaldSession;
 import static org.apache.openmeetings.web.app.Application.removeInvalidSession;
-import static org.apache.openmeetings.web.app.Application.removeOnlineUser;
 import static org.red5.logging.Red5LoggerFactory.getLogger;
 
 import java.util.Arrays;
@@ -121,7 +121,7 @@ public class WebSession extends Abstract
 
 	@Override
 	public void invalidate() {
-		removeOnlineUser(getClientByKeys(userId, getId()));
+		exit(getClientByKeys(userId, getId()));
 		super.invalidate();
 		userId = null;
 		rights = Collections.unmodifiableSet(Collections.<Right>emptySet());

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=1783168&r1=1783167&r2=1783168&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 Thu Feb 16 04:15:27 2017
@@ -25,8 +25,8 @@ import static org.apache.openmeetings.ut
 import static org.apache.openmeetings.util.OpenmeetingsVariables.LEVEL_USER;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.addOnlineUser;
+import static org.apache.openmeetings.web.app.Application.exit;
 import static org.apache.openmeetings.web.app.Application.getBean;
-import static org.apache.openmeetings.web.app.Application.removeOnlineUser;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getNamedFunction;
 import static org.apache.openmeetings.web.util.CallbackFunctionHelper.getParam;
@@ -36,23 +36,23 @@ 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;
 import java.util.Set;
 
+import org.apache.openmeetings.core.util.WebSocketHelper;
 import org.apache.openmeetings.db.dao.basic.NavigationDao;
+import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.basic.Client;
 import org.apache.openmeetings.db.entity.basic.Naviglobal;
 import org.apache.openmeetings.db.entity.basic.Navimain;
 import org.apache.openmeetings.db.entity.user.PrivateMessage;
 import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.web.app.Application;
-import org.apache.openmeetings.web.app.Client;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.menu.MainMenuItem;
 import org.apache.openmeetings.web.common.menu.MenuItem;
 import org.apache.openmeetings.web.common.menu.MenuPanel;
-import org.apache.openmeetings.web.room.menu.RoomMenuPanel;
 import org.apache.openmeetings.web.user.AboutDialog;
 import org.apache.openmeetings.web.user.MessageDialog;
 import org.apache.openmeetings.web.user.UserInfoDialog;
@@ -78,8 +78,6 @@ import org.apache.wicket.markup.html.pan
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.CompoundPropertyModel;
 import org.apache.wicket.protocol.http.request.WebClientInfo;
-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;
@@ -87,9 +85,6 @@ 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.request.cycle.RequestCycle;
 import org.apache.wicket.request.resource.JavaScriptResourceReference;
 import org.apache.wicket.util.time.Duration;
@@ -119,28 +114,7 @@ public class MainPanel extends Panel {
 
 		@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);
-				}
-			}
+			WebSocketHelper.sendClient(client, new byte[1]);
 		}
 	};
 	private final ExtendedClientProperties extProps = new ExtendedClientProperties();
@@ -249,7 +223,7 @@ public class MainPanel extends Panel {
 			@Override
 			protected void onConnect(ConnectedMessage msg) {
 				super.onConnect(msg);
-				client = new Client(getSession().getId(), msg.getKey().hashCode(), getUserId());
+				client = new Client(getSession().getId(), msg.getKey().hashCode(), getUserId(), getBean(UserDao.class));
 				addOnlineUser(client);
 				log.debug("WebSocketBehavior::onConnect [uid: {}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
 			}
@@ -279,11 +253,8 @@ public class MainPanel extends Panel {
 
 			private void closeHandler(AbstractClientMessage msg) {
 				//no chance to stop pingTimer here :(
-				if (client != null && client.getRoomId() != null) {
-					RoomMenuPanel.roomExit(client);
-				}
 				log.debug("WebSocketBehavior::closeHandler [uid: {}, session: {}, key: {}]", client.getUid(), msg.getSessionId(), msg.getKey());
-				removeOnlineUser(client);
+				exit(client);
 				client = null;
 			}
 		});

Modified: openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java
URL: http://svn.apache.org/viewvc/openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java?rev=1783168&r1=1783167&r2=1783168&view=diff
==============================================================================
--- openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java (original)
+++ openmeetings/application/branches/3.2.x/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomBroadcaster.java Thu Feb 16 04:15:27 2017
@@ -50,7 +50,7 @@ public class RoomBroadcaster {
 		sa.sendToScope(roomId, method, obj);
 	}
 
-	public static void sendUpdatedClient(org.apache.openmeetings.web.app.Client client) {
+	public static void sendUpdatedClient(org.apache.openmeetings.db.entity.basic.Client client) {
 		org.apache.openmeetings.db.entity.room.Client rcl = Application.get().updateClient(getClient(client.getUid()));
 		log.debug("-----------  sendUpdatedClient ");