| /* |
| * 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.openmeetings.app.remote.red5; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.openmeetings.app.OpenmeetingsVariables; |
| import org.openmeetings.app.conference.session.RoomClient; |
| import org.openmeetings.app.conference.whiteboard.BrowserStatus; |
| import org.openmeetings.app.conference.whiteboard.RoomStatus; |
| import org.openmeetings.app.conference.whiteboard.WhiteboardManagement; |
| import org.openmeetings.app.data.basic.Configurationmanagement; |
| import org.openmeetings.app.data.basic.Sessionmanagement; |
| import org.openmeetings.app.data.calendar.daos.MeetingMemberDaoImpl; |
| import org.openmeetings.app.data.calendar.management.AppointmentLogic; |
| import org.openmeetings.app.data.conference.Roommanagement; |
| import org.openmeetings.app.data.logs.ConferenceLogDaoImpl; |
| import org.openmeetings.app.data.user.Usermanagement; |
| import org.openmeetings.app.data.user.dao.UsersDaoImpl; |
| import org.openmeetings.app.persistence.beans.basic.Configuration; |
| import org.openmeetings.app.persistence.beans.calendar.Appointment; |
| import org.openmeetings.app.persistence.beans.calendar.MeetingMember; |
| import org.openmeetings.app.persistence.beans.rooms.Rooms; |
| import org.openmeetings.app.persistence.beans.user.Users; |
| import org.openmeetings.app.remote.FLVRecorderService; |
| import org.openmeetings.app.remote.WhiteBoardService; |
| import org.openmeetings.utils.math.CalendarPatterns; |
| import org.red5.client.net.rtmp.ClientExceptionHandler; |
| import org.red5.logging.Red5LoggerFactory; |
| import org.red5.server.adapter.ApplicationAdapter; |
| import org.red5.server.api.IClient; |
| import org.red5.server.api.IConnection; |
| import org.red5.server.api.Red5; |
| import org.red5.server.api.scope.IBasicScope; |
| import org.red5.server.api.scope.IBroadcastScope; |
| import org.red5.server.api.scope.IScope; |
| import org.red5.server.api.scope.ScopeType; |
| import org.red5.server.api.service.IPendingServiceCall; |
| import org.red5.server.api.service.IPendingServiceCallback; |
| import org.red5.server.api.service.IServiceCapableConnection; |
| import org.red5.server.api.stream.IBroadcastStream; |
| import org.red5.server.api.stream.IStreamListener; |
| import org.red5.server.api.stream.IStreamPacket; |
| import org.red5.server.net.rtmp.event.IRTMPEvent; |
| import org.red5.server.stream.StreamingProxy; |
| import org.red5.server.stream.message.RTMPMessage; |
| import org.slf4j.Logger; |
| import org.springframework.beans.factory.annotation.Autowired; |
| |
| public class ScopeApplicationAdapter extends ApplicationAdapter implements |
| IPendingServiceCallback { |
| |
| private static final Logger log = Red5LoggerFactory.getLogger( |
| ScopeApplicationAdapter.class, |
| OpenmeetingsVariables.webAppRootKey); |
| |
| @Autowired |
| private ClientListManager clientListManager; |
| @Autowired |
| private EmoticonsManager emoticonsManager; |
| @Autowired |
| private WhiteBoardService whiteBoardService; |
| @Autowired |
| private FLVRecorderService flvRecorderService; |
| @Autowired |
| private Configurationmanagement cfgManagement; |
| @Autowired |
| private AppointmentLogic appointmentLogic; |
| @Autowired |
| private Sessionmanagement sessionManagement; |
| @Autowired |
| private Usermanagement userManagement; |
| @Autowired |
| private Roommanagement roommanagement; |
| @Autowired |
| private ConferenceLogDaoImpl conferenceLogDao; |
| @Autowired |
| private UsersDaoImpl usersDao; |
| @Autowired |
| private MeetingMemberDaoImpl meetingMemberDao; |
| |
| private Map<String, StreamingProxy> streamingProxyMap = new HashMap<String, StreamingProxy>(); |
| // This is the Folder where all executables are written |
| // for windows platform |
| public static String batchFileDir = "webapps" + File.separatorChar + "ROOT" |
| + File.separatorChar + "jod" + File.separatorChar; |
| public static String lineSeperator = System.getProperty("line.separator"); |
| |
| // The Global WebApp Path |
| public static String webAppPath = ""; |
| public static String configDirName = "conf"; |
| public static String profilesPrefix = "profile_"; |
| |
| public static String configKeyCryptClassName = null; |
| public static Boolean whiteboardDrawStatus = null; |
| |
| private static long broadCastCounter = 0; |
| public static boolean initComplete = false; |
| |
| public synchronized void resultReceived(IPendingServiceCall arg0) { |
| // TODO Auto-generated method stub |
| } |
| |
| @Override |
| public synchronized boolean appStart(IScope scope) { |
| try { |
| webAppPath = scope.getResource("/").getFile().getAbsolutePath(); |
| batchFileDir = webAppPath + File.separatorChar + OpenmeetingsVariables.STREAMS_DIR |
| + File.separatorChar; |
| |
| log.debug("webAppPath : " + webAppPath); |
| log.debug("batchFileFir : " + batchFileDir); |
| |
| // Only load this Class one time |
| // Initially this value might by empty, because the DB is empty yet |
| Configuration conf = cfgManagement.getConfKey(3, "crypt_ClassName"); |
| if (conf != null) { |
| ScopeApplicationAdapter.configKeyCryptClassName = conf |
| .getConf_value(); |
| } |
| |
| // init your handler here |
| |
| // The scheduled Jobs did go into the Spring-Managed Beans, see |
| // schedulerJobs.service.xml |
| |
| // Spring Definition does not work here, its too early, Instance is |
| // not set yet |
| emoticonsManager.loadEmot(scope); |
| |
| for (String scopeName : scope.getScopeNames()) { |
| log.debug("scopeName :: " + scopeName); |
| } |
| |
| ScopeApplicationAdapter.initComplete = true; |
| |
| clientListManager.removeAllClients(); |
| |
| // OpenXGHttpClient.getInstance().openSIPgUserCreateTest(); |
| // OpenXGWrapperClient.getInstance().testConnection(); |
| // OpenXGClient.getInstance().testConnection(); |
| // ServerSocketMinaProcess serverSocketMinaProcess = new |
| // ServerSocketMinaProcess(); |
| |
| // serverSocketMinaProcess.doInitSocket(); |
| |
| } catch (Exception err) { |
| log.error("[appStart]", err); |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean roomConnect(IConnection conn, Object[] params) { |
| log.debug("roomConnect : "); |
| |
| try { |
| |
| IServiceCapableConnection service = (IServiceCapableConnection) conn; |
| String streamId = conn.getClient().getId(); |
| |
| boolean isAVClient = false; |
| if (params.length == 1) { |
| isAVClient = Boolean.parseBoolean(params[0].toString()); |
| } |
| |
| log.debug("### Client connected to OpenMeetings, register Client StreamId: " |
| + streamId + " scope " + conn.getScope().getName()+ " isAVClient "+isAVClient); |
| log.debug("params "+params); |
| |
| // Set StreamId in Client |
| service.invoke("setId", new Object[] { streamId }, this); |
| |
| String swfURL = ""; |
| if (conn.getConnectParams().get("swfUrl") != null) { |
| swfURL = conn.getConnectParams().get("swfUrl").toString(); |
| } |
| |
| RoomClient rcm = this.clientListManager.addClientListItem(streamId, |
| conn.getScope().getName(), conn.getRemotePort(), |
| conn.getRemoteAddress(), swfURL, isAVClient); |
| |
| // Log the User |
| conferenceLogDao.addConferenceLog("ClientConnect", |
| rcm.getUser_id(), streamId, null, rcm.getUserip(), |
| rcm.getScope(), rcm.getExternalUserId(), |
| rcm.getExternalUserType(), rcm.getMail(), |
| rcm.getFirstname(), rcm.getLastname()); |
| |
| } catch (Exception err) { |
| log.error("roomJoin", err); |
| } |
| return true; |
| } |
| |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public synchronized Map screenSharerAction(Map map) { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| Map returnMap = new HashMap(); |
| returnMap.put("result", "stopAll"); |
| |
| log.debug("----------- "); |
| |
| if (currentClient != null) { |
| |
| if (Boolean.valueOf(map.get("stopStreaming").toString())) { |
| log.debug("start streamPublishStart Is Screen Sharing -- Stop "); |
| |
| //Send message to all users |
| syncMessageToCurrentScope("stopRed5ScreenSharing", currentClient, false); |
| |
| if (currentClient.isStartRecording()) { |
| returnMap.put("result", "stopSharingOnly"); |
| } |
| |
| currentClient.setStartStreaming(false); |
| currentClient.setScreenPublishStarted(false); |
| |
| clientListManager.updateClientByStreamId( |
| currentClient.getStreamid(), currentClient); |
| } |
| if (Boolean.valueOf(map.get("stopRecording").toString())) { |
| if (currentClient.isStartStreaming()) { |
| returnMap.put("result", "stopRecordingOnly"); |
| } |
| |
| //Send message to all users |
| syncMessageToCurrentScope("stopRecordingMessage", currentClient, false); |
| |
| flvRecorderService.stopRecordAndSave( |
| current.getScope(), currentClient, null); |
| |
| currentClient.setStartRecording(false); |
| currentClient.setIsRecording(false); |
| |
| clientListManager.updateClientByStreamId( |
| currentClient.getStreamid(), currentClient); |
| } |
| if (Boolean.valueOf(map.get("stopPublishing").toString())) { |
| streamPublishingStop(); |
| if (currentClient.getIsScreenClient() && currentClient.isStartStreaming()) { |
| returnMap.put("result", "stopPublishingOnly"); |
| } |
| } |
| } |
| return returnMap; |
| } catch (Exception err) { |
| log.error("[screenSharerAction]", err); |
| } |
| return null; |
| } |
| |
| public List<RoomClient> checkRed5ScreenSharing() { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| |
| log.debug("checkScreenSharing -2- " + streamid); |
| |
| List<RoomClient> screenSharerList = new LinkedList<RoomClient>(); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| |
| HashMap<String, RoomClient> roomList = this.clientListManager |
| .getClientListByRoomAll(currentClient.getRoom_id()); |
| |
| for (Iterator<String> iter = roomList.keySet().iterator(); iter |
| .hasNext();) { |
| |
| RoomClient rcl = roomList.get(iter.next()); |
| |
| if (rcl.isStartStreaming()) { |
| screenSharerList.add(rcl); |
| } |
| |
| } |
| |
| return screenSharerList; |
| |
| } catch (Exception err) { |
| log.error("[checkScreenSharing]", err); |
| } |
| return null; |
| } |
| |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public synchronized Map setConnectionAsSharingClient(Map map) { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| // IServiceCapableConnection service = (IServiceCapableConnection) |
| // current; |
| |
| log.debug("### setConnectionAsSharingClient: "); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| if (currentClient != null) { |
| |
| boolean startRecording = Boolean.valueOf(map.get( |
| "startRecording").toString()); |
| boolean startStreaming = Boolean.valueOf(map.get( |
| "startStreaming").toString()); |
| |
| currentClient.setRoom_id(Long.parseLong(current.getScope() |
| .getName())); |
| |
| // Set this connection to be a RTMP-Java Client |
| currentClient.setIsScreenClient(true); |
| currentClient.setUser_id(Long.parseLong(map.get("user_id") |
| .toString())); |
| |
| if (startStreaming) { |
| currentClient.setStartStreaming(true); |
| } |
| |
| if (startRecording) { |
| currentClient.setStartRecording(true); |
| } |
| |
| currentClient.setOrganization_id(Long.parseLong(map.get( |
| "organization_id").toString())); |
| |
| this.clientListManager.updateClientByStreamId(current |
| .getClient().getId(), currentClient); |
| |
| Map returnMap = new HashMap(); |
| returnMap.put("alreadyPublished", false); |
| |
| // if is already started screen sharing, then there is no need |
| // to start it again |
| if (currentClient.isScreenPublishStarted()) { |
| returnMap.put("alreadyPublished", true); |
| } |
| |
| currentClient.setVX(Integer.parseInt(map.get("screenX") |
| .toString())); |
| currentClient.setVY(Integer.parseInt(map.get("screenY") |
| .toString())); |
| currentClient.setVWidth(Integer.parseInt(map.get("screenWidth") |
| .toString())); |
| currentClient.setVHeight(Integer.parseInt(map.get( |
| "screenHeight").toString())); |
| |
| log.debug("screen x,y,width,height " + currentClient.getVX() |
| + " " + currentClient.getVY() + " " |
| + currentClient.getVWidth() + " " |
| + currentClient.getVHeight()); |
| |
| log.debug("publishName :: " + map.get("publishName")); |
| |
| currentClient.setStreamPublishName(map.get("publishName") |
| .toString()); |
| |
| RoomClient currentScreenUser = this.clientListManager |
| .getClientByPublicSID(currentClient |
| .getStreamPublishName(), false); |
| |
| currentClient.setFirstname(currentScreenUser.getFirstname()); |
| currentClient.setLastname(currentScreenUser.getLastname()); |
| |
| // This is duplicated, but its not sure that in the meantime |
| // somebody requests this Client Object Info |
| this.clientListManager.updateClientByStreamId(current |
| .getClient().getId(), currentClient); |
| |
| if (startStreaming) { |
| returnMap.put("modus", "startStreaming"); |
| |
| log.debug("start streamPublishStart Is Screen Sharing "); |
| |
| //Send message to all users |
| syncMessageToCurrentScope("newRed5ScreenSharing", currentClient, false); |
| } else if (startRecording) { |
| returnMap.put("modus", "startRecording"); |
| |
| String recordingName = "Recording " |
| + CalendarPatterns |
| .getDateWithTimeByMiliSeconds(new Date()); |
| |
| flvRecorderService.recordMeetingStream(recordingName, "", false); |
| } else if (Boolean.valueOf(map.get("startPublishing").toString())) { |
| if (streamPublishingStart("" + map.get("publishingHost") |
| , "" + map.get("publishingApp") |
| , "" + map.get("publishingId"))) |
| { |
| returnMap.put("modus", "startPublishing"); |
| } |
| } |
| |
| return returnMap; |
| |
| } else { |
| throw new Exception("Could not find Screen Sharing Client " |
| + current.getClient().getId()); |
| } |
| |
| } catch (Exception err) { |
| log.error("[setConnectionAsSharingClient]", err); |
| } |
| return null; |
| } |
| |
| public synchronized List<Integer> listRoomBroadcast() { |
| List<Integer> broadcastList = new ArrayList<Integer>(); |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| Collection<Set<IConnection>> conCollection = current.getScope().getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn |
| .getClient().getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| if (!streamid.equals(rcl.getStreamid())) { |
| // It is not needed to send back |
| // that event to the actuall |
| // Moderator |
| // as it will be already triggered |
| // in the result of this Function |
| // in the Client |
| broadcastList.add(Long.valueOf(rcl.getBroadCastID()).intValue()); |
| } |
| } |
| } |
| } |
| } |
| return broadcastList; |
| } |
| |
| |
| /** |
| * this function is invoked directly after initial connecting |
| * |
| * @return |
| */ |
| public synchronized String getPublicSID() { |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| currentClient.setIsAVClient(false); |
| clientListManager.updateClientByStreamId(current.getClient().getId(), |
| currentClient); |
| return currentClient.getPublicSID(); |
| } |
| |
| /** |
| * this function is invoked after a reconnect |
| * |
| * @param newPublicSID |
| */ |
| public synchronized Boolean overwritePublicSID(String newPublicSID) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| if (currentClient == null) { |
| return false; |
| } |
| currentClient.setPublicSID(newPublicSID); |
| this.clientListManager.updateClientByStreamId(current.getClient() |
| .getId(), currentClient); |
| return true; |
| } catch (Exception err) { |
| log.error("[overwritePublicSID]", err); |
| } |
| return null; |
| } |
| |
| /** |
| * Logic must be before roomDisconnect cause otherwise you cannot throw a |
| * message to each one |
| * |
| */ |
| @Override |
| public void roomLeave(IClient client, IScope room) { |
| try { |
| |
| log.debug("roomLeave " + client.getId() + " " |
| + room.getClients().size() + " " + room.getContextPath() |
| + " " + room.getName()); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(client.getId()); |
| |
| // The Room Client can be null if the Client left the room by using |
| // logicalRoomLeave |
| if (currentClient != null) { |
| log.debug("currentClient IS NOT NULL"); |
| this.roomLeaveByScope(currentClient, room, true); |
| } |
| |
| } catch (Exception err) { |
| log.error("[roomLeave]", err); |
| } |
| } |
| |
| /** |
| * 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 synchronized void logicalRoomLeave() { |
| log.debug("logicalRoomLeave "); |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| |
| log.debug(streamid + " is leaving"); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| |
| this.roomLeaveByScope(currentClient, current.getScope(), true); |
| |
| } catch (Exception err) { |
| log.error("[logicalRoomLeave]", err); |
| } |
| } |
| |
| /** |
| * 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 |
| * to call it with proper values. |
| * |
| * @param currentClient |
| * @param currentScope |
| */ |
| public synchronized void roomLeaveByScope(RoomClient currentClient, |
| IScope currentScope, boolean removeUserFromSessionList) { |
| try { |
| |
| log.debug("currentClient " + currentClient); |
| log.debug("currentScope " + currentScope); |
| // log.debug("currentClient "+currentClient.getRoom_id()); |
| |
| Long room_id = currentClient.getRoom_id(); |
| |
| // Log the User |
| conferenceLogDao.addConferenceLog("roomLeave", |
| currentClient.getUser_id(), currentClient.getStreamid(), |
| room_id, currentClient.getUserip(), "", |
| currentClient.getExternalUserId(), |
| currentClient.getExternalUserType(), |
| currentClient.getMail(), currentClient.getFirstname(), |
| currentClient.getLastname()); |
| |
| // Remove User from Sync List's |
| if (room_id != null) { |
| this.whiteBoardService.removeUserFromAllLists(currentScope, |
| currentClient); |
| } |
| |
| log.debug("removing USername " + currentClient.getUsername() + " " |
| + currentClient.getConnectedSince() + " streamid: " |
| + currentClient.getStreamid()); |
| |
| // stop and save any recordings |
| if (currentClient.getIsRecording()) { |
| log.debug("*** roomLeave Current Client is Recording - stop that"); |
| // StreamService.stopRecordAndSave(currentScope, |
| // currentClient.getRoomRecordingName(), currentClient); |
| |
| this.flvRecorderService.stopRecordAndSave(currentScope, |
| currentClient, null); |
| |
| // set to true and overwrite the default one cause otherwise no |
| // notification is send |
| currentClient.setIsRecording(true); |
| } |
| |
| // Notify all clients of the same currentScope (room) with domain |
| // and room except the current disconnected cause it could throw an exception |
| log.debug("currentScope " + currentScope); |
| |
| if (currentScope != null && currentScope.getConnections() != null) { |
| // Notify Users of the current Scope |
| Collection<Set<IConnection>> conCollection = currentScope |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection cons : conset) { |
| if (cons != null) { |
| if (cons instanceof IServiceCapableConnection) { |
| |
| log.debug("sending roomDisconnect to " + cons |
| + " client id " |
| + cons.getClient().getId()); |
| |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(cons.getClient() |
| .getId()); |
| |
| /* |
| * Check if the Client does still exist on the |
| * list |
| */ |
| if (rcl != null) { |
| |
| /* |
| * Do not send back to sender, but actually |
| * all other clients should receive this |
| * message swagner 01.10.2009 |
| */ |
| if (!currentClient.getStreamid().equals( |
| rcl.getStreamid())) { |
| |
| // add Notification if another user isrecording |
| log.debug("###########[roomLeave]"); |
| if (rcl.getIsRecording()) { |
| log.debug("*** roomLeave Any Client is Recording - stop that"); |
| this.flvRecorderService |
| .stopRecordingShowForClient( |
| cons, currentClient); |
| } |
| |
| //If the user was a avclient, we do not broadcast a message about that to everybody |
| if (currentClient.getIsAVClient()) { |
| continue; |
| } |
| |
| if (rcl.getIsScreenClient() != null && rcl |
| .getIsScreenClient()) { |
| // screen sharing clients do not receive events |
| continue; |
| } else if (rcl.getIsAVClient()) { |
| // AVClients or potential AVClients do not receive events |
| continue; |
| } |
| |
| // Send to all connected users |
| ((IServiceCapableConnection) cons) |
| .invoke("roomDisconnect", |
| new Object[] { currentClient },this); |
| log.debug("sending roomDisconnect to " + cons); |
| } |
| } else { |
| log.debug("For this StreamId: " |
| + cons.getClient().getId() |
| + " There is no Client in the List anymore"); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if (removeUserFromSessionList) { |
| this.clientListManager.removeClient(currentClient.getStreamid()); |
| } |
| } catch (Exception err) { |
| log.error("[roomLeaveByScope]", err); |
| } |
| } |
| |
| /** |
| * This method handles the Event after a stream has been added all connected |
| * Clients in the same room will get a notification |
| * |
| * @return void |
| * |
| */ |
| @Override |
| public synchronized void streamPublishStart(IBroadcastStream stream) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| |
| //We make a second object the has the reference to the object |
| //that we will use to send to all participents |
| RoomClient clientObjectSendToSync = currentClient; |
| |
| // Notify all the clients that the stream had been started |
| log.debug("start streamPublishStart broadcast start: " |
| + stream.getPublishedName() + " CONN " + current); |
| |
| // In case its a screen sharing we start a new Video for that |
| if (currentClient.getIsScreenClient()) { |
| |
| currentClient.setScreenPublishStarted(true); |
| |
| this.clientListManager.updateClientByStreamId(current |
| .getClient().getId(), currentClient); |
| } |
| //If its an audio/video client then send the session object with the full |
| //data to everybody |
| else if (currentClient.getIsAVClient()) { |
| clientObjectSendToSync = this.clientListManager.getClientByPublicSID( |
| currentClient.getPublicSID(), false); |
| } |
| |
| log.debug("newStream SEND: "+currentClient); |
| |
| // Notify all users of the same Scope |
| // We need to iterate through the streams to catch if anybody is recording |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| |
| if (rcl == null) { |
| log.debug("RCL IS NULL newStream SEND"); |
| continue; |
| } |
| |
| log.debug("check send to "+rcl); |
| |
| if (rcl.getPublicSID() == "") { |
| log.debug("publicSID IS NULL newStream SEND"); |
| continue; |
| } |
| if (rcl.getIsRecording()) { |
| log.debug("RCL getIsRecording newStream SEND"); |
| this.flvRecorderService |
| .addRecordingByStreamId(current, |
| streamid, currentClient, |
| rcl.getFlvRecordingId()); |
| } |
| if (rcl.getIsAVClient()) { |
| log.debug("RCL getIsAVClient newStream SEND"); |
| continue; |
| } |
| if (rcl.getIsScreenClient() == null || rcl.getIsScreenClient()) { |
| log.debug("RCL getIsScreenClient newStream SEND"); |
| continue; |
| } |
| |
| if (rcl.getPublicSID().equals(currentClient.getPublicSID())) { |
| log.debug("RCL publicSID is equal newStream SEND"); |
| continue; |
| } |
| |
| log.debug("RCL SEND is equal newStream SEND "+rcl.getPublicSID()+" || "+rcl.getUserport()); |
| |
| IServiceCapableConnection iStream = (IServiceCapableConnection) conn; |
| iStream.invoke("newStream", |
| new Object[] { clientObjectSendToSync }, |
| this); |
| |
| } |
| } |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[streamPublishStart]", err); |
| } |
| } |
| |
| public IBroadcastScope getBroadcastScope(IScope scope, String name) { |
| IBasicScope basicScope = scope.getBasicScope(ScopeType.BROADCAST, name); |
| if (!(basicScope instanceof IBroadcastScope)) { |
| return null; |
| } else { |
| return (IBroadcastScope) basicScope; |
| } |
| } |
| |
| public boolean streamPublishingStart(String host, String app, String id) { |
| final boolean[] result = {true}; |
| final IConnection conn = Red5.getConnectionLocal(); |
| RoomClient rc = clientListManager.getClientByStreamId(conn.getClient().getId()); |
| String publishName = rc.getStreamPublishName(); |
| |
| if (rc.getIsScreenClient() && rc.isStartStreaming()) { |
| IScope scope = conn.getScope(); |
| IBroadcastStream stream = getBroadcastStream(scope, publishName); |
| IBroadcastScope bsScope = getBroadcastScope(scope, publishName); |
| final StreamingProxy proxy = new StreamingProxy(); |
| proxy.setHost(host); |
| proxy.setApp(app); |
| proxy.setPort(1935); |
| proxy.init(); |
| proxy.setExceptionHandler(new ClientExceptionHandler() { |
| public void handleException(Throwable throwable) { |
| result[0] = false; |
| HashMap<String, Object> params = new HashMap<String, Object>(); |
| params.put("stopPublishing", true); |
| params.put("error", throwable.getMessage()); |
| ((IServiceCapableConnection)conn).invoke( |
| "screenSharerAction" |
| , new Object[] { params } |
| , ScopeApplicationAdapter.this); |
| } |
| }); |
| bsScope.subscribe(proxy, null); |
| proxy.start(id, "live", null); |
| streamingProxyMap.put(publishName, proxy); |
| stream.addStreamListener(new IStreamListener() { |
| public void packetReceived(IBroadcastStream stream, IStreamPacket packet) { |
| try { |
| RTMPMessage m = RTMPMessage.build((IRTMPEvent)packet, packet.getTimestamp()); |
| proxy.pushMessage(null, m); |
| } catch (Exception e) { |
| log.error("Exception while sending proxy message", e); |
| } |
| } |
| }); |
| } |
| return result[0]; |
| } |
| |
| public void streamPublishingStop() { |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient rc = clientListManager.getClientByStreamId(current.getClient().getId()); |
| String publishName = rc.getStreamPublishName(); |
| |
| if (rc.getIsScreenClient() && publishName != null) { |
| IScope scope = current.getScope(); |
| IBroadcastStream stream = getBroadcastStream(scope, publishName); |
| StreamingProxy proxy = streamingProxyMap.remove(publishName); |
| if (proxy != null) { |
| proxy.stop(); |
| IBroadcastScope bsScope = getBroadcastScope(scope, stream.getPublishedName()); |
| if (bsScope != null) { |
| bsScope.unsubscribe(proxy); |
| } |
| } |
| } |
| } |
| |
| /** |
| * This method handles the Event after a stream has been removed all |
| * connected Clients in the same room will get a notification |
| * |
| * @return void |
| * |
| */ |
| @Override |
| public synchronized void streamBroadcastClose(IBroadcastStream stream) { |
| |
| // Notify all the clients that the stream had been closed |
| log.debug("start streamBroadcastClose broadcast close: " |
| + stream.getPublishedName()); |
| try { |
| streamPublishingStop(); |
| |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient rcl = clientListManager.getClientByStreamId(current.getClient().getId()); |
| sendClientBroadcastNotifications(stream, "closeStream", rcl); |
| } catch (Exception e) { |
| log.error("[streamBroadcastClose]", e); |
| } |
| } |
| |
| /** |
| * This method handles the notification room-based |
| * |
| * @return void |
| * |
| */ |
| private synchronized void sendClientBroadcastNotifications( |
| IBroadcastStream stream, String clientFunction, RoomClient rc) { |
| try { |
| |
| // Store the local so that we do not send notification to ourself |
| // back |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| |
| if (currentClient == null) { |
| |
| // In case the client has already left(kicked) this message |
| // might be thrown later then the RoomLeave |
| // event and the currentClient is already gone |
| // The second Use-Case where the currentClient is maybe null is |
| // if we remove the client because its a Zombie/Ghost |
| |
| return; |
| |
| } |
| // Notify all the clients that the stream had been started |
| log.debug("sendClientBroadcastNotifications: " |
| + stream.getPublishedName()); |
| log.debug("sendClientBroadcastNotifications : " + currentClient |
| + " " + currentClient.getStreamid()); |
| |
| // Notify all clients of the same scope (room) |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| if (conn.equals(current)) { |
| // there is a Bug in the current implementation |
| // of the appDisconnect |
| if (clientFunction.equals("closeStream")) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn |
| .getClient().getId()); |
| if (clientFunction.equals("closeStream") |
| && rcl.getIsRecording()) { |
| log.debug("*** stopRecordingShowForClient Any Client is Recording - stop that"); |
| // StreamService.stopRecordingShowForClient(conn, |
| // currentClient, |
| // rcl.getRoomRecordingName(), false); |
| this.flvRecorderService |
| .stopRecordingShowForClient( |
| conn, currentClient); |
| } |
| // Don't notify current client |
| current.ping(); |
| } |
| continue; |
| } else { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| if (rcl != null) { |
| if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| log.debug("is this users still alive? :" |
| + rcl); |
| // conn.ping(); |
| IServiceCapableConnection iStream = (IServiceCapableConnection) conn; |
| // log.info("IServiceCapableConnection ID " |
| // + iStream.getClient().getId()); |
| iStream.invoke(clientFunction, |
| new Object[] { rc }, this); |
| } |
| |
| log.debug("sending notification to " + conn |
| + " ID: "); |
| |
| // if this close stream event then stop the |
| // recording of this stream |
| if (clientFunction.equals("closeStream") |
| && rcl.getIsRecording()) { |
| log.debug("*** +++++++ ######## sendClientBroadcastNotifications Any Client is Recording - stop that"); |
| // StreamService.stopRecordingShowForClient(conn, |
| // currentClient, |
| // rcl.getRoomRecordingName(), false); |
| this.flvRecorderService |
| .stopRecordingShowForClient( |
| conn, currentClient); |
| } |
| } |
| |
| } |
| } |
| } |
| } |
| } |
| } catch (Exception err) { |
| log.error("[sendClientBroadcastNotifications]", err); |
| } |
| } |
| |
| |
| /** |
| * Adds a Moderator by its publicSID |
| * |
| * @param publicSID |
| * @return |
| */ |
| public synchronized Long addModerator(String publicSID) { |
| try { |
| |
| log.debug("*..*addModerator publicSID: " + publicSID); |
| |
| // String streamid = current.getClient().getId(); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| |
| if (currentClient == null) { |
| return -1L; |
| } |
| Long room_id = currentClient.getRoom_id(); |
| |
| currentClient.setIsMod(true); |
| // Put the mod-flag to true for this client |
| this.clientListManager.updateClientByStreamId( |
| currentClient.getStreamid(), currentClient); |
| |
| List<RoomClient> currentMods = this.clientListManager |
| .getCurrentModeratorByRoom(room_id); |
| |
| //Send message to all users |
| syncMessageToCurrentScope("setNewModeratorByList", currentMods, true); |
| |
| } catch (Exception err) { |
| log.error("[addModerator]", err); |
| } |
| return -1L; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public void setNewCursorPosition(Object item) { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| |
| // log.debug("[setNewCursorPosition]"+item); |
| |
| @SuppressWarnings("rawtypes") |
| Map cursor = (Map) item; |
| cursor.put("streamPublishName", |
| currentClient.getStreamPublishName()); |
| |
| // log.debug("[setNewCursorPosition x]"+cursor.get("cursor_x")); |
| // log.debug("[setNewCursorPosition y]"+cursor.get("cursor_y")); |
| // log.debug("[setNewCursorPosition publicSID]"+cursor.get("publicSID")); |
| |
| // Notify all users of the same Scope |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| if (conn.equals(current)) { |
| continue; |
| } else { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| // log.debug("is this users still alive? :"+rcl); |
| // Check if the Client is in the same room |
| // and same domain |
| IServiceCapableConnection iStream = (IServiceCapableConnection) conn; |
| // log.info("IServiceCapableConnection ID " |
| // + iStream.getClient().getId()); |
| iStream.invoke("newRed5ScreenCursor", |
| new Object[] { cursor }, this); |
| // log.debug("send Notification to"); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[setNewCursorPosition]", err); |
| } |
| } |
| |
| public synchronized Long removeModerator(String publicSID) { |
| try { |
| |
| log.debug("*..*addModerator publicSID: " + publicSID); |
| |
| IConnection current = Red5.getConnectionLocal(); |
| // String streamid = current.getClient().getId(); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| |
| if (currentClient == null) { |
| return -1L; |
| } |
| Long room_id = currentClient.getRoom_id(); |
| |
| currentClient.setIsMod(false); |
| // Put the mod-flag to true for this client |
| this.clientListManager.updateClientByStreamId( |
| currentClient.getStreamid(), currentClient); |
| |
| List<RoomClient> currentMods = this.clientListManager |
| .getCurrentModeratorByRoom(room_id); |
| |
| // Notify all clients of the same scope (room) |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| log.debug("Send Flag to Client: " |
| + rcl.getUsername()); |
| if (conn instanceof IServiceCapableConnection) { |
| ((IServiceCapableConnection) conn).invoke( |
| "setNewModeratorByList", |
| new Object[] { currentMods }, this); |
| log.debug("sending setNewModeratorByList to " |
| + conn); |
| } |
| } |
| } |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[addModerator]", err); |
| } |
| return -1L; |
| } |
| |
| public synchronized Long setBroadCastingFlag(String publicSID, |
| boolean value, Integer interviewPodId) { |
| try { |
| |
| log.debug("*..*setBroadCastingFlag publicSID: " + publicSID); |
| |
| IConnection current = Red5.getConnectionLocal(); |
| // String streamid = current.getClient().getId(); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| |
| if (currentClient == null) { |
| return -1L; |
| } |
| |
| currentClient.setIsBroadcasting(value); |
| currentClient.setInterviewPodId(interviewPodId); |
| |
| // Put the mod-flag to true for this client |
| this.clientListManager.updateClientByStreamId( |
| currentClient.getStreamid(), currentClient); |
| |
| // Notify all clients of the same scope (room) |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| if (rcl == null) { |
| continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| continue; |
| } else if (rcl.getIsAVClient()) { |
| continue; |
| } |
| |
| log.debug("Send Flag to Client: " |
| + rcl.getUsername()); |
| if (conn instanceof IServiceCapableConnection) { |
| ((IServiceCapableConnection) conn).invoke( |
| "setNewBroadCastingFlag", |
| new Object[] { currentClient }, this); |
| log.debug("sending setNewBroadCastingFlag to " |
| + conn); |
| } |
| } |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[setBroadCastingFlag]", err); |
| } |
| return -1L; |
| } |
| |
| public synchronized Long giveExclusiveAudio(String publicSID) { |
| try { |
| |
| log.debug("*..*giveExclusiveAudio publicSID: " + publicSID); |
| |
| IConnection current = Red5.getConnectionLocal(); |
| // String streamid = current.getClient().getId(); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| |
| if (currentClient == null) { |
| return -1L; |
| } |
| |
| // Put the mod-flag to true for this client |
| currentClient.setMicMuted(false); |
| this.clientListManager.updateClientByStreamId( |
| currentClient.getStreamid(), currentClient); |
| |
| // Notify all clients of the same scope (room) |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| if (rcl != currentClient) { |
| rcl.setMicMuted(true); |
| this.clientListManager.updateClientByStreamId( |
| rcl.getStreamid(), rcl); |
| } |
| log.debug("Send Flag to Client: " |
| + rcl.getUsername()); |
| if (conn instanceof IServiceCapableConnection) { |
| ((IServiceCapableConnection) conn).invoke( |
| "receiveExclusiveAudioFlag", |
| new Object[] { currentClient }, this); |
| log.debug("sending receiveExclusiveAudioFlag to " |
| + conn); |
| } |
| } |
| } |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[giveExclusiveAudio]", err); |
| } |
| return -1L; |
| } |
| |
| public synchronized Long switchMicMuted(String publicSID, boolean mute) { |
| try { |
| log.debug("*..*switchMicMuted publicSID: " + publicSID); |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| if (currentClient == null) { |
| return -1L; |
| } |
| |
| currentClient.setMicMuted(mute); |
| this.clientListManager.updateClientByStreamId( |
| currentClient.getStreamid(), currentClient); |
| |
| HashMap<Integer, Object> newMessage = new HashMap<Integer, Object>(); |
| newMessage.put(0, "updateMuteStatus"); |
| newMessage.put(1, currentClient); |
| this.sendMessageWithClient(newMessage); |
| |
| } catch (Exception err) { |
| log.error("[switchMicMuted]", err); |
| } |
| return 0L; |
| } |
| |
| public synchronized Boolean getMicMutedByPublicSID(String publicSID) { |
| try { |
| RoomClient currentClient = this.clientListManager.getClientByPublicSID(publicSID, false); |
| if (currentClient == null) { |
| return true; |
| } |
| |
| //Put the mod-flag to true for this client |
| Boolean muted = currentClient.getMicMuted(); |
| if (null == muted) { |
| muted = true; |
| } |
| |
| return muted; |
| } catch (Exception err) { |
| log.error("[getMicMutedByPublicSID]",err); |
| } |
| return true; |
| } |
| |
| /** |
| * Invoked by a User whenever he want to become moderator this is needed, |
| * 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 |
| */ |
| public synchronized Long applyForModeration(String publicSID) { |
| try { |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| |
| List<RoomClient> currentModList = this.clientListManager |
| .getCurrentModeratorByRoom(currentClient.getRoom_id()); |
| |
| if (currentModList.size() > 0) { |
| return 2L; |
| } else { |
| // No moderator in this room at the moment |
| Rooms room = roommanagement.getRoomById(currentClient |
| .getRoom_id()); |
| |
| if (room.getIsModeratedRoom()) { |
| return 3L; |
| } else { |
| return 1L; |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[applyForModeration]", err); |
| } |
| return -1L; |
| } |
| |
| /** |
| * there will be set an attribute called "broadCastCounter" this is the name |
| * this user will publish his stream |
| * |
| * @return long broadCastId |
| */ |
| public synchronized long getBroadCastId() { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| currentClient.setBroadCastID(broadCastCounter++); |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| return currentClient.getBroadCastID(); |
| } catch (Exception err) { |
| log.error("[getBroadCastId]", err); |
| } |
| return -1; |
| } |
| |
| /** |
| * this must be set _after_ the Video/Audio-Settings have been chosen (see |
| * editrecordstream.lzx) but _before_ anything else happens, it cannot be |
| * applied _after_ the stream has started! avsettings can be: av - video and |
| * audio a - audio only v - video only n - no a/v only static image |
| * furthermore |
| * |
| * @param avsetting |
| * @param newMessage |
| * @return |
| */ |
| public synchronized RoomClient setUserAVSettings(String avsettings, |
| Object newMessage, Integer vWidth, Integer vHeight, |
| long room_id, String publicSID, Integer interviewPodId) { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| currentClient.setAvsettings(avsettings); |
| currentClient.setRoom_id(room_id); |
| currentClient.setPublicSID(publicSID); |
| currentClient.setIsAVClient(true); |
| currentClient.setVWidth(vWidth); |
| currentClient.setVHeight(vHeight); |
| currentClient.setInterviewPodId(interviewPodId); |
| // Long room_id = currentClient.getRoom_id(); |
| this.clientListManager.updateAVClientByStreamId(streamid, |
| currentClient); |
| |
| HashMap<String, Object> hsm = new HashMap<String, Object>(); |
| hsm.put("client", currentClient); |
| hsm.put("message", newMessage); |
| |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| ((IServiceCapableConnection) conn).invoke( |
| "sendVarsToMessageWithClient", |
| new Object[] { hsm }, this); |
| } |
| } |
| } |
| } |
| } |
| |
| return currentClient; |
| } catch (Exception err) { |
| log.error("[setUserAVSettings]", err); |
| } |
| return null; |
| } |
| |
| /* |
| * checks if the user is allowed to apply for Moderation |
| */ |
| public synchronized Boolean checkRoomValues(Long room_id) { |
| try { |
| |
| // appointed meeting or moderated Room? |
| Rooms room = roommanagement.getRoomById(room_id); |
| |
| // not really - default logic |
| if (room.getAppointment() == null || room.getAppointment() == false) { |
| |
| if (room.getIsModeratedRoom()) { |
| |
| // if this is a Moderated Room then the Room can be only |
| // locked off by the Moderator Bit |
| List<RoomClient> clientModeratorListRoom = this.clientListManager |
| .getCurrentModeratorByRoom(room_id); |
| |
| // If there is no Moderator yet and we are asking for it |
| // then deny it |
| // cause at this moment, the user should wait untill a |
| // Moderator enters the Room |
| if (clientModeratorListRoom.size() == 0) { |
| return false; |
| } else { |
| return true; |
| } |
| |
| } else { |
| return true; |
| } |
| |
| } else { |
| |
| // FIXME: TODO: For Rooms that are created as Appointment we |
| // have to check that too |
| // but I don't know yet the Logic behind it - swagner 19.06.2009 |
| return true; |
| |
| } |
| |
| } catch (Exception err) { |
| log.error("[checkRoomValues]", err); |
| } |
| return false; |
| } |
| |
| /** |
| * 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/> |
| * <br/> |
| * Some rules:<br/> |
| * <ul> |
| * <li>If it is a room that was created through the calendar, the user that |
| * organized the room will be moderator, the param Boolean becomeModerator |
| * will be ignored then</li> |
| * <li>In regular rooms you can use the param Boolean becomeModerator to set |
| * any user to become a moderator of the room</li> |
| * </ul> |
| * <br/> |
| * If a new moderator is detected a Push Call to all current users of the |
| * room is invoked "setNewModeratorByList" to notify them of the new |
| * moderator<br/> |
| * <br/> |
| * And the end of the mechanism a push call with the new client-object |
| * and all the informations about the new user is send to every user of the |
| * current conference room<br/> |
| * <br/> |
| * @param room_id |
| * @param colorObj |
| * @return |
| */ |
| public synchronized RoomStatus setRoomValues(Long room_id, |
| Boolean becomeModerator, Boolean isSuperModerator, |
| Long organization_id, String colorObj) { |
| try { |
| |
| // Return Object |
| RoomStatus roomStatus = new RoomStatus(); |
| |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| currentClient.setRoom_id(room_id); |
| currentClient.setIsAVClient(false); |
| currentClient.setRoomEnter(new Date()); |
| currentClient.setOrganization_id(organization_id); |
| |
| currentClient.setUsercolor(colorObj); |
| |
| // Inject externalUserId if nothing is set yet |
| if (currentClient.getExternalUserId() == null) { |
| Users us = usersDao.getUser(currentClient.getUser_id()); |
| if (us != null) { |
| currentClient.setExternalUserId(us.getExternalUserId()); |
| currentClient.setExternalUserType(us.getExternalUserType()); |
| } |
| } |
| |
| // This can be set without checking for Moderation Flag |
| currentClient.setIsSuperModerator(isSuperModerator); |
| |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| |
| Rooms room = roommanagement.getRoomById(room_id); |
| if (room.getShowMicrophoneStatus()) { |
| currentClient.setCanGiveAudio(true); |
| } |
| |
| // Log the User |
| conferenceLogDao.addConferenceLog("roomEnter", |
| currentClient.getUser_id(), streamid, room_id, |
| currentClient.getUserip(), "", |
| currentClient.getExternalUserId(), |
| currentClient.getExternalUserType(), |
| currentClient.getMail(), currentClient.getFirstname(), |
| currentClient.getLastname()); |
| |
| log.debug("##### setRoomValues : " + currentClient); |
| |
| // Check for Moderation LogicalRoom ENTER |
| HashMap<String, RoomClient> clientListRoom = this.clientListManager |
| .getRoomClients(room_id); |
| |
| // appointed meeting or moderated Room? => Check Max Users first |
| if (room.getNumberOfPartizipants() != null |
| && clientListRoom.size() > room.getNumberOfPartizipants()) { |
| roomStatus.setRoomFull(true); |
| return roomStatus; |
| } |
| |
| // default logic for non regular rooms |
| if (room.getAppointment() == null || room.getAppointment() == false) { |
| |
| if (room.getIsModeratedRoom()) { |
| |
| // if this is a Moderated Room then the Room can be only |
| // locked off by the Moderator Bit |
| // List<RoomClient> clientModeratorListRoom = |
| // this.clientListManager.getCurrentModeratorByRoom(room_id); |
| |
| // If there is no Moderator yet we have to check if the |
| // current User has the Bit set to true to |
| // become one, otherwise he won't get Moderation and has to |
| // wait |
| if (becomeModerator) { |
| currentClient.setIsMod(true); |
| |
| // There is a need to send an extra Event here, cause at |
| // this moment there could be |
| // already somebody in the Room waiting |
| |
| // Update the Client List |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| |
| List<RoomClient> modRoomList = this.clientListManager |
| .getCurrentModeratorByRoom(currentClient.getRoom_id()); |
| |
| //Sync message to everybody |
| syncMessageToCurrentScope("setNewModeratorByList", modRoomList, false); |
| |
| } else { |
| // The current User is not a Teacher/Admin or whatever |
| // Role that should get the |
| // Moderation |
| currentClient.setIsMod(false); |
| } |
| |
| } else { |
| |
| // If this is a normal Room Moderator rules : first come, |
| // first draw ;-) |
| log.debug("setRoomValues : Room" |
| + room_id |
| + " not appointed! Moderator rules : first come, first draw ;-)"); |
| if (clientListRoom.size() == 1) { |
| log.debug("Room is empty so set this user to be moderation role"); |
| currentClient.setIsMod(true); |
| } else { |
| log.debug("Room is already somebody so set this user not to be moderation role"); |
| |
| if (becomeModerator) { |
| currentClient.setIsMod(true); |
| |
| // Update the Client List |
| this.clientListManager.updateClientByStreamId( |
| streamid, currentClient); |
| |
| List<RoomClient> modRoomList = this.clientListManager |
| .getCurrentModeratorByRoom(currentClient |
| .getRoom_id()); |
| |
| // There is a need to send an extra Event here, |
| // cause at this moment there could be |
| // already somebody in the Room waiting -swagner check this comment, 20.01.2012 |
| |
| //Sync message to everybody |
| syncMessageToCurrentScope("setNewModeratorByList", modRoomList, false); |
| |
| } else { |
| // The current User is not a Teacher/Admin or |
| // whatever Role that should get the Moderation |
| currentClient.setIsMod(false); |
| } |
| |
| } |
| |
| } |
| |
| // Update the Client List |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| |
| } else { |
| |
| // If this is an Appointment then the Moderator will be set to |
| // the Invitor |
| |
| Appointment ment = appointmentLogic |
| .getAppointmentByRoom(room_id); |
| |
| List<MeetingMember> members = meetingMemberDao |
| .getMeetingMemberByAppointmentId(ment |
| .getAppointmentId()); |
| |
| Long userIdInRoomClient = currentClient.getUser_id(); |
| |
| boolean found = false; |
| boolean moderator_set = false; |
| |
| // Check if current user is set to moderator |
| for (int i = 0; i < members.size(); i++) { |
| MeetingMember member = members.get(i); |
| |
| // only persistent users can schedule a meeting |
| // user-id is only set for registered users |
| if (member.getUserid() != null) { |
| log.debug("checking user " + member.getFirstname() |
| + " for moderator role - ID : " |
| + member.getUserid().getUser_id()); |
| |
| if (member.getUserid().getUser_id() |
| .equals(userIdInRoomClient)) { |
| found = true; |
| |
| if (member.getInvitor()) { |
| log.debug("User " |
| + userIdInRoomClient |
| + " is moderator due to flag in MeetingMember record"); |
| currentClient.setIsMod(true); |
| |
| // Update the Client List |
| this.clientListManager.updateClientByStreamId( |
| streamid, currentClient); |
| |
| List<RoomClient> modRoomList = this.clientListManager |
| .getCurrentModeratorByRoom(currentClient |
| .getRoom_id()); |
| |
| // There is a need to send an extra Event here, cause at this moment |
| // there could be already somebody in the Room waiting |
| |
| //Sync message to everybody |
| syncMessageToCurrentScope("setNewModeratorByList", modRoomList, false); |
| |
| moderator_set = true; |
| this.clientListManager.updateClientByStreamId( |
| streamid, currentClient); |
| break; |
| } else { |
| log.debug("User " |
| + userIdInRoomClient |
| + " is NOT moderator due to flag in MeetingMember record"); |
| currentClient.setIsMod(false); |
| this.clientListManager.updateClientByStreamId( |
| streamid, currentClient); |
| break; |
| } |
| } else { |
| if (member.getInvitor()) |
| moderator_set = true; |
| } |
| } else { |
| if (member.getInvitor()) |
| moderator_set = true; |
| } |
| |
| } |
| |
| if (!found) { |
| log.debug("User " |
| + userIdInRoomClient |
| + " could not be found as MeetingMember -> definitely no moderator"); |
| currentClient.setIsMod(false); |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| } else { |
| // if current user is part of the member list, but moderator |
| // couldn't be retrieved : first come, first draw! |
| if (clientListRoom.size() == 1 && moderator_set == false) { |
| log.debug(""); |
| currentClient.setIsMod(true); |
| |
| // Update the Client List |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| |
| List<RoomClient> modRoomList = this.clientListManager |
| .getCurrentModeratorByRoom(currentClient |
| .getRoom_id()); |
| |
| // There is a need to send an extra Event here, cause at |
| // this moment there could be |
| // already somebody in the Room waiting |
| |
| //Sync message to everybody |
| syncMessageToCurrentScope("setNewModeratorByList", modRoomList, false); |
| |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| } |
| } |
| |
| } |
| |
| |
| //Sync message to everybody |
| syncMessageToCurrentScope("addNewUser", currentClient, false); |
| |
| //Status object for Shared Browsing |
| BrowserStatus browserStatus = (BrowserStatus) current.getScope() |
| .getAttribute("browserStatus"); |
| |
| if (browserStatus == null) { |
| browserStatus = new BrowserStatus(); |
| } |
| |
| // RoomStatus roomStatus = new RoomStatus(); |
| |
| // FIXME: Rework Client Object to DTOs |
| roomStatus.setClientMap(clientListRoom); |
| roomStatus.setBrowserStatus(browserStatus); |
| |
| return roomStatus; |
| } catch (Exception err) { |
| log.error("[setRoomValues]", err); |
| } |
| return null; |
| } |
| |
| /** |
| * 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 |
| */ |
| public synchronized RoomClient setUsernameReconnect(String SID, |
| Long userId, String username, String firstname, String lastname, |
| String picture_uri) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| |
| currentClient.setUsername(username); |
| currentClient.setUser_id(userId); |
| currentClient.setPicture_uri(picture_uri); |
| currentClient.setUserObject(userId, username, firstname, lastname); |
| |
| // Update Session Data |
| sessionManagement.updateUserWithoutSession(SID, userId); |
| |
| Users user = userManagement.getUserById(userId); |
| |
| if (user != null) { |
| currentClient.setExternalUserId(user.getExternalUserId()); |
| currentClient.setExternalUserType(user.getExternalUserType()); |
| } |
| |
| // only fill this value from User-Record |
| // cause invited users have non |
| // you cannot set the firstname,lastname from the UserRecord |
| Users us = usersDao.getUser(userId); |
| if (us != null && us.getPictureuri() != null) { |
| // set Picture-URI |
| currentClient.setPicture_uri(us.getPictureuri()); |
| } |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| return currentClient; |
| } catch (Exception err) { |
| log.error("[setUsername]", err); |
| } |
| return null; |
| } |
| |
| /** |
| * this is set initial directly after login/loading language |
| * |
| * @param userId |
| * @param username |
| * @param firstname |
| * @param lastname |
| * @param orgdomain |
| * @return |
| */ |
| public synchronized RoomClient setUsernameAndSession(String SID, |
| Long userId, String username, String firstname, String lastname) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(streamid); |
| |
| currentClient.setUsername(username); |
| currentClient.setUser_id(userId); |
| currentClient.setUserObject(userId, username, firstname, lastname); |
| |
| // Update Session Data |
| log.debug("UDPATE SESSION " + SID + ", " + userId); |
| sessionManagement.updateUserWithoutSession(SID, userId); |
| |
| Users user = userManagement.getUserById(userId); |
| |
| if (user != null) { |
| currentClient.setExternalUserId(user.getExternalUserId()); |
| currentClient.setExternalUserType(user.getExternalUserType()); |
| } |
| |
| // only fill this value from User-Record |
| // cause invited users have non |
| // you cannot set the firstname,lastname from the UserRecord |
| Users us = usersDao.getUser(userId); |
| if (us != null && us.getPictureuri() != null) { |
| // set Picture-URI |
| currentClient.setPicture_uri(us.getPictureuri()); |
| } |
| this.clientListManager.updateClientByStreamId(streamid, |
| currentClient); |
| return currentClient; |
| } catch (Exception err) { |
| log.error("[setUsername]", err); |
| } |
| return null; |
| } |
| |
| /** |
| * used by the Screen-Sharing Servlet to trigger events |
| * |
| * @param room_id |
| * @param message |
| * @return |
| */ |
| public synchronized HashMap<String, RoomClient> sendMessageByRoomAndDomain( |
| Long room_id, Object message) { |
| HashMap<String, RoomClient> roomClientList = new HashMap<String, RoomClient>(); |
| try { |
| |
| log.debug("sendMessageByRoomAndDomain " + room_id); |
| |
| IScope globalScope = getContext().getGlobalScope(); |
| |
| IScope webAppKeyScope = globalScope |
| .getScope(OpenmeetingsVariables.webAppRootKey); |
| |
| log.debug("webAppKeyScope " + webAppKeyScope); |
| |
| IScope scopeHibernate = webAppKeyScope.getScope(room_id.toString()); |
| // IScope scopeHibernate = webAppKeyScope.getScope("hibernate"); |
| |
| if (scopeHibernate != null) { |
| |
| Collection<Set<IConnection>> conCollection = webAppKeyScope |
| .getScope(room_id.toString()).getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| if (conn instanceof IServiceCapableConnection) { |
| // RoomClient rcl = |
| // this.clientListManager.getClientByStreamId(conn.getClient().getId()); |
| ((IServiceCapableConnection) conn).invoke( |
| "newMessageByRoomAndDomain", |
| new Object[] { message }, this); |
| |
| // log.debug("sending newMessageByRoomAndDomain to " |
| // + conn); |
| } |
| } |
| } |
| } |
| } |
| |
| } else { |
| log.debug("sendMessageByRoomAndDomain servlet not yet started - roomID : '" |
| + room_id + "'"); |
| } |
| |
| } catch (Exception err) { |
| log.error("[getClientListBYRoomAndDomain]", err); |
| } |
| return roomClientList; |
| } |
| |
| public synchronized List<RoomClient> getCurrentModeratorList() { |
| try { |
| log.debug("*..*getCurrentModerator id: "); |
| |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| Long room_id = currentClient.getRoom_id(); |
| |
| // log.debug("Who is this moderator? "+currentMod); |
| |
| return this.clientListManager.getCurrentModeratorByRoom(room_id); |
| } catch (Exception err) { |
| log.error("[getCurrentModerator]", err); |
| } |
| return null; |
| } |
| |
| /** |
| * This Function is triggered from the Whiteboard |
| * |
| * @param whiteboardObj |
| * @return |
| */ |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public synchronized void sendVars(ArrayList whiteboardObjParam) { |
| // |
| try { |
| |
| // In previous version this has been always a Map, now its a List |
| // so I re-wrapp that class to be a Map again. |
| // swagner 13.02.2009 |
| // log.debug("*..*sendVars1: " + whiteboardObjParam); |
| // log.debug("*..*sendVars2: " + whiteboardObjParam.getClass()); |
| // log.debug("*..*sendVars3: " + |
| // whiteboardObjParam.getClass().getName()); |
| |
| Map whiteboardObj = new HashMap(); |
| int i = 0; |
| for (Iterator iter = whiteboardObjParam.iterator(); iter.hasNext();) { |
| Object obj = iter.next(); |
| // log.debug("obj"+obj); |
| whiteboardObj.put(i, obj); |
| i++; |
| } |
| |
| // Map whiteboardObj = (Map) whiteboardObjParam; |
| |
| // Check if this User is the Mod: |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| if (currentClient == null) { |
| return; |
| } |
| |
| Long room_id = currentClient.getRoom_id(); |
| |
| String action = whiteboardObj.get(2).toString(); |
| |
| // log.debug("***** sendVars: " + actionObject.get(0)); |
| |
| if (action != null && action.equals("whiteboardObj")) { |
| // Update Whiteboard Object |
| List actionObject = (List) whiteboardObj.get(3); |
| WhiteboardManagement.getInstance().updateWhiteboardObject( |
| room_id, actionObject); |
| } else if (action != null && action.equals("moveMap")) { |
| // Update Whiteboard Object |
| List actionObject = (List) whiteboardObj.get(3); |
| WhiteboardManagement.getInstance().updateWhiteboardObjectPos( |
| room_id, actionObject); |
| } else { |
| // Store event in list |
| WhiteboardManagement.getInstance().addWhiteBoardObject(room_id, |
| whiteboardObj); |
| } |
| |
| boolean showDrawStatus = getWhiteboardDrawStatus(); |
| |
| // Notify all Clients of that Scope (Room) |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| |
| if (conn.getClient().getId() |
| .equals(current.getClient().getId())) { |
| continue; |
| } |
| |
| RoomClient rcl = this.clientListManager |
| .getSyncClientByStreamId(conn.getClient() |
| .getId()); |
| |
| if (rcl == null) { |
| continue; |
| } |
| |
| if (!currentClient.getStreamid().equals( |
| rcl.getStreamid())) { |
| ((IServiceCapableConnection) conn) |
| .invoke("sendVarsToWhiteboard", |
| new Object[] { |
| (showDrawStatus ? currentClient |
| : null), |
| whiteboardObj }, this); |
| } |
| } |
| } |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[sendVars]", err); |
| } |
| } |
| |
| /** |
| * This Function is triggered from the Whiteboard |
| * |
| * @param whiteboardObj |
| * @return |
| */ |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| public synchronized void sendVarsByWhiteboardId( |
| ArrayList whiteboardObjParam, Long whiteboardId) { |
| // |
| try { |
| |
| Map whiteboardObj = new HashMap(); |
| int i = 0; |
| for (Iterator iter = whiteboardObjParam.iterator(); iter.hasNext();) { |
| Object obj = iter.next(); |
| // log.debug("obj"+obj); |
| whiteboardObj.put(i, obj); |
| i++; |
| } |
| |
| // Check if this User is the Mod: |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| if (currentClient == null) { |
| return; |
| } |
| |
| Long room_id = currentClient.getRoom_id(); |
| |
| // log.debug("***** sendVars: " + whiteboardObj); |
| |
| // Store event in list |
| String action = whiteboardObj.get(2).toString(); |
| |
| if (action.equals("deleteMindMapNodes")) { |
| |
| // Simulate Single Delete Events for z-Index |
| List actionObject = (List) whiteboardObj.get(3); |
| |
| List<List> itemObjects = (List) actionObject.get(3); |
| |
| Map whiteboardTempObj = new HashMap(); |
| whiteboardTempObj.put(2, "delete"); |
| |
| for (List itemObject : itemObjects) { |
| |
| List<Object> tempActionObject = new LinkedList<Object>(); |
| tempActionObject.add("mindmapnode"); |
| tempActionObject.add(itemObject.get(0)); // z-Index -8 |
| tempActionObject.add(null); // simulate -7 |
| tempActionObject.add(null); // simulate -6 |
| tempActionObject.add(null); // simulate -5 |
| tempActionObject.add(null); // simulate -4 |
| tempActionObject.add(null); // simulate -3 |
| tempActionObject.add(null); // simulate -2 |
| tempActionObject.add(itemObject.get(1)); // Object-Name -1 |
| |
| whiteboardTempObj.put(3, tempActionObject); |
| |
| WhiteboardManagement.getInstance().addWhiteBoardObjectById( |
| room_id, whiteboardTempObj, whiteboardId); |
| |
| } |
| |
| } else { |
| |
| WhiteboardManagement.getInstance().addWhiteBoardObjectById( |
| room_id, whiteboardObj, whiteboardId); |
| |
| } |
| |
| // This is no longer necessary |
| // boolean ismod = currentClient.getIsMod(); |
| |
| // log.debug("*..*ismod: " + ismod); |
| |
| // if (ismod) { |
| |
| Map<String, Object> sendObject = new HashMap<String, Object>(); |
| sendObject.put("id", whiteboardId); |
| sendObject.put("param", whiteboardObjParam); |
| |
| boolean showDrawStatus = getWhiteboardDrawStatus(); |
| |
| // Notify all Clients of that Scope (Room) |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| if (conn.getClient().getId() |
| .equals(current.getClient().getId())) { |
| continue; |
| } |
| |
| RoomClient rcl = this.clientListManager |
| .getSyncClientByStreamId(conn.getClient() |
| .getId()); |
| |
| if (rcl == null) { |
| continue; |
| } |
| |
| if (!currentClient.getStreamid().equals( |
| rcl.getStreamid())) { |
| ((IServiceCapableConnection) conn).invoke( |
| "sendVarsToWhiteboardById", |
| new Object[] { |
| showDrawStatus ? currentClient |
| : null, sendObject }, |
| this); |
| } |
| } |
| } |
| } |
| } |
| |
| // return numberOfUsers; |
| // } else { |
| // // log.debug("*..*you are not allowed to send: "+ismod); |
| // return -1; |
| // } |
| } catch (Exception err) { |
| log.error("[sendVarsByWhiteboardId]", err); |
| } |
| } |
| |
| public synchronized int sendVarsModeratorGeneral(Object vars) { |
| log.debug("*..*sendVars: " + vars); |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| // Long room_id = currentClient.getRoom_id(); |
| |
| log.debug("***** id: " + currentClient.getStreamid()); |
| |
| boolean ismod = currentClient.getIsMod(); |
| |
| if (ismod) { |
| log.debug("CurrentScope :" + current.getScope().getName()); |
| // Send to all Clients of the same Scope |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| // log.debug("*..*idremote: " + |
| // rcl.getStreamid()); |
| // log.debug("*..*my idstreamid: " + |
| // currentClient.getStreamid()); |
| if (!currentClient.getStreamid().equals( |
| rcl.getStreamid())) { |
| ((IServiceCapableConnection) conn) |
| .invoke("sendVarsToModeratorGeneral", |
| new Object[] { vars }, |
| this); |
| // log.debug("sending sendVarsToModeratorGeneral to " |
| // + conn); |
| } |
| } |
| } |
| } |
| } |
| } |
| return 1; |
| } else { |
| // log.debug("*..*you are not allowed to send: "+ismod); |
| return -1; |
| } |
| } catch (Exception err) { |
| log.error("[sendVarsModeratorGeneral]", err); |
| } |
| return -1; |
| } |
| |
| public synchronized int sendMessage(Object newMessage) { |
| try { |
| |
| syncMessageToCurrentScope("sendVarsToMessage", newMessage, false); |
| |
| } catch (Exception err) { |
| log.error("[sendMessage]", err); |
| } |
| return 1; |
| } |
| |
| public synchronized int sendMessageAll(Object newMessage) { |
| try { |
| |
| syncMessageToCurrentScope("sendVarsToMessage", newMessage, true); |
| |
| } catch (Exception err) { |
| log.error("[sendMessage]", err); |
| } |
| return 1; |
| } |
| |
| /** |
| * send status for shared browsing to all members except self |
| * @param newMessage |
| * @return |
| */ |
| @SuppressWarnings({ "rawtypes" }) |
| public synchronized int sendBrowserMessageToMembers(Object newMessage) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| |
| List newMessageList = (List) newMessage; |
| |
| String action = newMessageList.get(0).toString(); |
| |
| BrowserStatus browserStatus = (BrowserStatus) current.getScope() |
| .getAttribute("browserStatus"); |
| |
| if (browserStatus == null) { |
| browserStatus = new BrowserStatus(); |
| } |
| |
| if (action.equals("initBrowser") || action.equals("newBrowserURL")) { |
| browserStatus.setBrowserInited(true); |
| browserStatus.setCurrentURL(newMessageList.get(1).toString()); |
| } else if (action.equals("closeBrowserURL")) { |
| browserStatus.setBrowserInited(false); |
| } |
| |
| current.getScope().setAttribute("browserStatus", browserStatus); |
| |
| syncMessageToCurrentScope("sendVarsToMessage", newMessage, false); |
| |
| } catch (Exception err) { |
| log.error("[sendMessage]", err); |
| } |
| return 1; |
| } |
| |
| /** |
| * wrapper method |
| * @param newMessage |
| * @return |
| */ |
| public synchronized int sendMessageToMembers(Object newMessage) { |
| try { |
| |
| //Sync to all users of current scope |
| syncMessageToCurrentScope("sendVarsToMessage", newMessage, false); |
| |
| } catch (Exception err) { |
| log.error("[sendMessage]", err); |
| } |
| return 1; |
| } |
| |
| /** |
| * 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> |
| * <li>do not send to clients that are screen sharing clients</li> |
| * <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 |
| * @param newMessage |
| * @param sendSelf |
| * @return |
| */ |
| public synchronized int syncMessageToCurrentScope(String remoteMethodName, Object newMessage, boolean sendSelf) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| |
| // Send to all Clients of that Scope(Room) |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| |
| if (rcl == null) { |
| // RoomClient can be null if there are network problems |
| continue; |
| } else if (rcl.getIsScreenClient() != null && rcl |
| .getIsScreenClient()) { |
| // screen sharing clients do not receive events |
| continue; |
| } else if (rcl.getIsAVClient()) { |
| // AVClients or potential AVClients do not receive events |
| continue; |
| } else if (current.getClient().getId().equals( |
| conn.getClient().getId()) && !sendSelf) { |
| //Do not send back to self |
| continue; |
| } |
| |
| ((IServiceCapableConnection) conn).invoke( |
| remoteMethodName, new Object[] { newMessage }, this); |
| |
| } |
| } |
| } |
| } |
| } catch (Exception err) { |
| log.error("[syncMessageToCurrentScope]", err); |
| } |
| return 1; |
| } |
| |
| /** |
| * wrapper method |
| * @param newMessage |
| * @return |
| */ |
| public synchronized int sendMessageWithClient(Object newMessage) { |
| try { |
| sendMessageWithClientWithSyncObject(newMessage, true); |
| |
| } catch (Exception err) { |
| log.error("[sendMessageWithClient] ", err); |
| return -1; |
| } |
| return 1; |
| } |
| |
| /** |
| * wrapper method |
| * @param newMessage |
| * @param sync |
| * @return |
| */ |
| public synchronized int sendMessageWithClientWithSyncObject(Object newMessage, boolean sync) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| HashMap<String, Object> hsm = new HashMap<String, Object>(); |
| hsm.put("client", currentClient); |
| hsm.put("message", newMessage); |
| |
| //Sync to all users of current scope |
| syncMessageToCurrentScope("sendVarsToMessageWithClient", hsm, sync); |
| |
| } catch (Exception err) { |
| log.error("[sendMessageWithClient] ", err); |
| return -1; |
| } |
| return 1; |
| } |
| |
| /** |
| * 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 |
| */ |
| public synchronized int sendMessageById(Object newMessage, String clientId, |
| IScope scope) { |
| try { |
| log.debug("### sendMessageById ###" + clientId); |
| |
| HashMap<String, Object> hsm = new HashMap<String, Object>(); |
| hsm.put("message", newMessage); |
| |
| // broadcast Message to specific user with id inside the same Scope |
| Collection<Set<IConnection>> conCollection = scope.getConnections(); |
| |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| if (conn instanceof IServiceCapableConnection) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| // log.debug("### sendMessageById 1 ###"+clientId); |
| // log.debug("### sendMessageById 2 ###"+conn.getClient().getId()); |
| if (conn.getClient().getId().equals(clientId)) { |
| ((IServiceCapableConnection) conn).invoke( |
| "sendVarsToMessageWithClient", |
| new Object[] { hsm }, this); |
| // log.debug("sendingsendVarsToMessageWithClient ByID to " |
| // + conn); |
| } |
| } |
| } |
| } |
| } |
| } |
| } catch (Exception err) { |
| log.error("[sendMessageWithClient] ", err); |
| return -1; |
| } |
| return 1; |
| } |
| |
| /** |
| * Sends a message to a user in the same room by its clientId |
| * |
| * @param newMessage |
| * @param clientId |
| * @return |
| */ |
| public synchronized int sendMessageWithClientById(Object newMessage, |
| String clientId) { |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| log.debug("### sendMessageWithClientById ###" + clientId); |
| |
| HashMap<String, Object> hsm = new HashMap<String, Object>(); |
| hsm.put("client", currentClient); |
| hsm.put("message", newMessage); |
| |
| // broadcast Message to specific user with id inside the same Scope |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| if (conn instanceof IServiceCapableConnection) { |
| // log.debug("### sendMessageWithClientById 1 ###"+clientId); |
| // log.debug("### sendMessageWithClientById 2 ###"+conn.getClient().getId()); |
| if (conn.getClient().getId().equals(clientId)) { |
| ((IServiceCapableConnection) conn).invoke( |
| "sendVarsToMessageWithClient", |
| new Object[] { hsm }, this); |
| // log.debug("sendingsendVarsToMessageWithClient ByID to " |
| // + conn); |
| } |
| } |
| } |
| } |
| } |
| } |
| } catch (Exception err) { |
| log.error("[sendMessageWithClient] ", err); |
| return -1; |
| } |
| return 1; |
| } |
| |
| public synchronized void sendMessageWithClientByPublicSID(Object message, |
| String publicSID) { |
| try { |
| // ApplicationContext appCtx = getContext().getApplicationContext(); |
| IScope globalScope = getContext().getGlobalScope(); |
| |
| IScope webAppKeyScope = globalScope |
| .getScope(OpenmeetingsVariables.webAppRootKey); |
| |
| // log.debug("webAppKeyScope "+webAppKeyScope); |
| |
| // Get Room Id to send it to the correct Scope |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| |
| if (currentClient == null) { |
| throw new Exception( |
| "Could not Find RoomClient on List publicSID: " |
| + publicSID); |
| } |
| // default Scope Name |
| String scopeName = "hibernate"; |
| if (currentClient.getRoom_id() != null) { |
| scopeName = currentClient.getRoom_id().toString(); |
| } |
| |
| IScope scopeHibernate = webAppKeyScope.getScope(scopeName); |
| |
| // log.debug("scopeHibernate "+scopeHibernate); |
| |
| if (scopeHibernate != null) { |
| // Notify the clients of the same scope (room) with user_id |
| |
| Collection<Set<IConnection>> conCollection = webAppKeyScope |
| .getScope(scopeName).getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient() |
| .getId()); |
| if (rcl != null) { |
| if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| // log.debug("rcl "+rcl+" rcl.getUser_id(): "+rcl.getPublicSID()+" publicSID: "+publicSID+ |
| // " IS EQUAL? "+rcl.getPublicSID().equals(publicSID)); |
| if (rcl.getPublicSID().equals(publicSID)) { |
| // log.debug("IS EQUAL "); |
| ((IServiceCapableConnection) conn) |
| .invoke("newMessageByRoomAndDomain", |
| new Object[] { message }, |
| this); |
| log.debug("newMessageByRoomAndDomain RPC:newMessageByRoomAndDomain" |
| + message); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| } else { |
| // Scope not yet started |
| } |
| } catch (Exception err) { |
| log.error("[sendMessageWithClient] ", err); |
| err.printStackTrace(); |
| } |
| } |
| |
| public synchronized void sendMessageWithClientByPublicSIDOrUser( |
| Object message, String publicSID, Long user_id) { |
| try { |
| // ApplicationContext appCtx = getContext().getApplicationContext(); |
| |
| IScope globalScope = getContext().getGlobalScope(); |
| |
| IScope webAppKeyScope = globalScope |
| .getScope(OpenmeetingsVariables.webAppRootKey); |
| |
| // log.debug("webAppKeyScope "+webAppKeyScope); |
| |
| // Get Room Id to send it to the correct Scope |
| RoomClient currentClient = this.clientListManager |
| .getClientByPublicSID(publicSID, false); |
| |
| if (currentClient == null) { |
| currentClient = this.clientListManager |
| .getClientByUserId(user_id); |
| } |
| |
| Collection<Set<IConnection>> conCollection = null; |
| |
| if (currentClient == null) { |
| // Must be from a previous session, search for user in current |
| // scope |
| IConnection current = Red5.getConnectionLocal(); |
| // Notify all Clients of that Scope (Room) |
| conCollection = current.getScope().getConnections(); |
| } else { |
| // default Scope Name |
| String scopeName = "hibernate"; |
| if (currentClient.getRoom_id() != null) { |
| scopeName = currentClient.getRoom_id().toString(); |
| } |
| |
| IScope scopeHibernate = webAppKeyScope.getScope(scopeName); |
| |
| if (scopeHibernate != null) { |
| conCollection = webAppKeyScope.getScope(scopeName) |
| .getConnections(); |
| } |
| } |
| |
| // log.debug("scopeHibernate "+scopeHibernate); |
| |
| // Notify the clients of the same scope (room) with user_id |
| |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| if (rcl != null) { |
| if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| // log.debug("rcl "+rcl+" rcl.getUser_id(): "+rcl.getPublicSID()+" publicSID: "+publicSID+ |
| // " IS EQUAL? "+rcl.getPublicSID().equals(publicSID)); |
| if (rcl.getPublicSID().equals(publicSID)) { |
| // log.debug("IS EQUAL "); |
| ((IServiceCapableConnection) conn).invoke( |
| "newMessageByRoomAndDomain", |
| new Object[] { message }, this); |
| log.debug("sendMessageWithClientByPublicSID RPC:newMessageByRoomAndDomain" |
| + message); |
| } else if (user_id != 0 |
| && rcl.getUser_id() != null |
| && rcl.getUser_id().equals(user_id)) { |
| ((IServiceCapableConnection) conn).invoke( |
| "newMessageByRoomAndDomain", |
| new Object[] { message }, this); |
| log.debug("sendMessageWithClientByPublicSID RPC:newMessageByRoomAndDomain" |
| + message); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| } catch (Exception err) { |
| log.error("[sendMessageWithClient] ", err); |
| err.printStackTrace(); |
| } |
| } |
| |
| public synchronized Boolean getInterviewRecordingStatus() { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| |
| if (rcl.getIsRecording() != null |
| && rcl.getIsRecording()) { |
| return true; |
| } |
| |
| } |
| } |
| } |
| |
| return false; |
| } catch (Exception err) { |
| log.error("[getInterviewRecordingStatus]", err); |
| } |
| |
| return null; |
| } |
| |
| public synchronized Boolean startInterviewRecording() { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| |
| if (rcl.getIsRecording() != null |
| && rcl.getIsRecording()) { |
| return false; |
| } |
| |
| } |
| } |
| } |
| |
| RoomClient current_rcl = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| // Also set the Recording Flag to Record all Participants that enter |
| // later |
| current_rcl.setIsRecording(true); |
| this.clientListManager.updateClientByStreamId(current.getClient() |
| .getId(), current_rcl); |
| |
| Map<String, String> interviewStatus = new HashMap<String, String>(); |
| interviewStatus.put("action", "start"); |
| |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| |
| if (rcl == null) { |
| continue; |
| } else if (rcl.getIsAVClient()) { |
| continue; |
| } else if (rcl.getIsScreenClient() != null && rcl.getIsScreenClient()) { |
| continue; |
| } |
| |
| ((IServiceCapableConnection) conn).invoke( |
| "interviewStatus", |
| new Object[] { interviewStatus }, this); |
| log.debug("-- interviewStatus" + interviewStatus); |
| |
| } |
| } |
| } |
| |
| String recordingName = "Interview " |
| + CalendarPatterns.getDateWithTimeByMiliSeconds(new Date()); |
| |
| this.flvRecorderService |
| .recordMeetingStream(recordingName, "", true); |
| |
| return true; |
| |
| } catch (Exception err) { |
| log.debug("[startInterviewRecording]", err); |
| } |
| return null; |
| } |
| |
| @SuppressWarnings({ "rawtypes" }) |
| public synchronized Boolean sendRemoteCursorEvent(String streamid, |
| Map messageObj) { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| |
| if (rcl.getStreamid() != null |
| && rcl.getStreamid().equals(streamid)) { |
| ((IServiceCapableConnection) conn).invoke( |
| "sendRemoteCursorEvent", |
| new Object[] { messageObj }, this); |
| log.debug("sendRemoteCursorEvent messageObj" |
| + messageObj); |
| } |
| |
| } |
| |
| } |
| } |
| } |
| } catch (Exception err) { |
| log.debug("[sendRemoteCursorEvent]", err); |
| } |
| return null; |
| } |
| |
| //FIXME: legacy code, needs to be removed |
| public boolean checkSharerSession() { |
| return true; |
| } |
| |
| /** |
| * Stop the recording of the streams and send event to connected users of scope |
| * |
| * @return |
| */ |
| public synchronized Boolean stopInterviewRecording() { |
| try { |
| |
| IConnection current = Red5.getConnectionLocal(); |
| |
| boolean found = false; |
| Long flvRecordingId = null; |
| |
| Collection<Set<IConnection>> conCollection = current.getScope() |
| .getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| |
| RoomClient rcl = this.clientListManager |
| .getClientByStreamId(conn.getClient().getId()); |
| |
| if (rcl.getIsRecording() != null |
| && rcl.getIsRecording()) { |
| |
| rcl.setIsRecording(false); |
| |
| flvRecordingId = rcl.getFlvRecordingId(); |
| |
| rcl.setFlvRecordingId(null); |
| |
| // Reset the Recording Flag to Record all |
| // Participants that enter later |
| this.clientListManager.updateClientByStreamId(conn |
| .getClient().getId(), rcl); |
| |
| found = true; |
| } |
| |
| } |
| } |
| } |
| |
| if (!found) { |
| return false; |
| } |
| |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| this.flvRecorderService.stopRecordAndSave(scope, currentClient, |
| flvRecordingId); |
| |
| Map<String, String> interviewStatus = new HashMap<String, String>(); |
| interviewStatus.put("action", "stop"); |
| |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| ((IServiceCapableConnection) conn).invoke( |
| "interviewStatus", |
| new Object[] { interviewStatus }, this); |
| log.debug("sendMessageWithClientByPublicSID interviewStatus" |
| + interviewStatus); |
| |
| } |
| } |
| } |
| |
| return true; |
| |
| } catch (Exception err) { |
| log.debug("[startInterviewRecording]", err); |
| } |
| return null; |
| } |
| |
| /** |
| * Get all ClientList Objects of that room and domain Used in |
| * lz.applyForModeration.lzx |
| * |
| * @return |
| */ |
| public synchronized HashMap<String, RoomClient> getClientListScope() { |
| HashMap<String, RoomClient> roomClientList = new HashMap<String, RoomClient>(); |
| try { |
| IConnection current = Red5.getConnectionLocal(); |
| RoomClient currentClient = this.clientListManager |
| .getClientByStreamId(current.getClient().getId()); |
| |
| return this.clientListManager.getClientListByRoom(currentClient.getRoom_id()); |
| |
| } catch (Exception err) { |
| log.debug("[getClientListScope]", err); |
| } |
| return roomClientList; |
| } |
| |
| private boolean getWhiteboardDrawStatus() { |
| if (ScopeApplicationAdapter.whiteboardDrawStatus == null) { |
| String drawStatus = cfgManagement.getConfValue("show.whiteboard.draw.status", String.class, "0"); |
| ScopeApplicationAdapter.whiteboardDrawStatus = "1".equals(drawStatus); |
| } |
| return ScopeApplicationAdapter.whiteboardDrawStatus; |
| } |
| |
| public String getCryptKey() { |
| try { |
| |
| if (ScopeApplicationAdapter.configKeyCryptClassName == null) { |
| Configuration conf = cfgManagement.getConfKey(3, |
| "crypt_ClassName"); |
| |
| if (conf != null) { |
| ScopeApplicationAdapter.configKeyCryptClassName = conf |
| .getConf_value(); |
| } |
| } |
| |
| return ScopeApplicationAdapter.configKeyCryptClassName; |
| } catch (Exception err) { |
| log.error("[getCryptKey]", err); |
| } |
| return null; |
| } |
| |
| public String getExclusiveAudioKeyCode() { |
| Configuration conf = cfgManagement.getConfKey(3, "exclusive.audio.keycode"); |
| if (null != conf) { |
| return conf.getConf_value(); |
| } else { |
| return null; |
| } |
| } |
| |
| public synchronized IScope getRoomScope(String room) { |
| try { |
| |
| IScope globalScope = getContext().getGlobalScope(); |
| IScope webAppKeyScope = globalScope |
| .getScope(OpenmeetingsVariables.webAppRootKey); |
| |
| String scopeName = "hibernate"; |
| // If set then its a NON default Scope |
| if (room.length() != 0) { |
| scopeName = room; |
| } |
| |
| IScope scopeHibernate = webAppKeyScope.getScope(scopeName); |
| |
| return scopeHibernate; |
| } catch (Exception err) { |
| log.error("[getRoomScope]", err); |
| } |
| return null; |
| } |
| |
| /* |
| * SIP transport methods |
| */ |
| |
| public synchronized void updateSipTransport() { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager.getClientByStreamId(streamid); |
| log.debug("getSipConferenceMembersNumber: " + roommanagement.getSipConferenceMembersNumber(currentClient.getRoom_id())); |
| String newNumber = "("+Integer.toString(roommanagement.getSipConferenceMembersNumber(currentClient.getRoom_id())-1)+")"; |
| if(!newNumber.equals(currentClient.getLastname())) { |
| currentClient.setLastname(newNumber); |
| this.clientListManager.updateClientByStreamId(streamid, currentClient); |
| log.debug("updateSipTransport: {}, {}, {}, {}", new Object[]{currentClient.getPublicSID(), |
| currentClient.getRoom_id(), currentClient.getFirstname(), currentClient.getLastname()}); |
| sendMessageWithClient(new String[]{"personal",currentClient.getFirstname(),currentClient.getLastname()}); |
| } |
| } |
| |
| /** |
| * Perform call to specified phone number and join to conference |
| * @param number to call |
| */ |
| public synchronized void joinToConfCall(String number) { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| RoomClient currentClient = this.clientListManager.getClientByStreamId(streamid); |
| Rooms rooms = roommanagement.getRoomById(currentClient.getRoom_id()); |
| log.debug("asterisk -rx \"originate Local/" + number + "@rooms extension " + rooms.getSipNumber() + "@rooms\""); |
| try { |
| Runtime.getRuntime().exec(new String[]{"asterisk", "-rx", "originate Local/" + number + "@rooms extension " + rooms.getSipNumber() + "@rooms"}); |
| } catch (IOException e) { |
| log.error("Executing asterisk originate error: ", e); |
| } |
| } |
| |
| public synchronized String getSipNumber(Long room_id) { |
| Rooms rooms = roommanagement.getRoomById(room_id); |
| if(rooms != null) { |
| log.debug("getSipNumber: room_id: {}, sipNumber: {}", new Object[]{room_id, rooms.getSipNumber()}); |
| return rooms.getSipNumber(); |
| } |
| return null; |
| } |
| |
| public synchronized void setSipTransport(Long room_id, String publicSID, String broadCastId) { |
| IConnection current = Red5.getConnectionLocal(); |
| String streamid = current.getClient().getId(); |
| // Notify all clients of the same scope (room) |
| RoomClient currentClient = this.clientListManager.getClientByStreamId(streamid); |
| currentClient.setRoom_id(room_id); |
| currentClient.setRoomEnter(new Date()); |
| currentClient.setFirstname("SIP Transport"); |
| currentClient.setLastname("("+Integer.toString(roommanagement.getSipConferenceMembersNumber(room_id)-1)+")"); |
| currentClient.setBroadCastID(Long.parseLong(broadCastId)); |
| currentClient.setIsBroadcasting(true); |
| currentClient.setPublicSID(publicSID); |
| currentClient.setAvsettings("av"); |
| currentClient.setVWidth(120); |
| currentClient.setVHeight(90); |
| this.clientListManager.updateClientByStreamId(streamid, currentClient); |
| |
| Collection<Set<IConnection>> conCollection = current |
| .getScope().getConnections(); |
| for (Set<IConnection> conset : conCollection) { |
| for (IConnection conn : conset) { |
| if (conn != null) { |
| RoomClient rcl = this.clientListManager.getClientByStreamId(conn.getClient().getId()); |
| if (rcl == null) { |
| // continue; |
| } else if (rcl.getIsScreenClient() != null |
| && rcl.getIsScreenClient()) { |
| // continue; |
| } else { |
| if (!streamid.equals(rcl.getStreamid())) { |
| // It is not needed to send back |
| // that event to the actuall |
| // Moderator |
| // as it will be already triggered |
| // in the result of this Function |
| // in the Client |
| if (conn instanceof IServiceCapableConnection) { |
| ((IServiceCapableConnection) conn).invoke("addNewUser", new Object[]{currentClient}, this); |
| ((IServiceCapableConnection) conn).invoke("newStream", new Object[]{currentClient}, this); |
| log.debug("sending setSipTransport to " |
| + conn); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |