/*
* (C) Copyright 2014 Kurento (http://kurento.org/)
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-2.1.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/
package com.kurento.kmf.demo.group;
import static com.google.common.collect.Lists.newArrayListWithExpectedSize;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.JsonObject;
import com.kurento.kmf.jsonrpcconnector.Session;
import com.kurento.kmf.media.MediaPipeline;
/**
* @author Ivan Gracia (izanmail@gmail.com)
*
*/
public class Room {
private final Logger log = LoggerFactory.getLogger(Room.class);
private final ConcurrentMap<String, Participant> participants = new ConcurrentHashMap<>();
private final MediaPipeline pipeline;
private final String roomName;
/**
* @return the roomName
*/
public String getRoomName() {
return roomName;
}
public Room(String roomName, MediaPipeline pipeline) {
this.roomName = roomName;
this.pipeline = pipeline;
log.info("ROOM {} has been created", roomName);
}
@PreDestroy
private void shutdown() {
for (Participant participant : participants.values()) {
try {
participant.close();
} catch (IOException e) {
// nothing to do here
}
}
}
public Participant join(String name, Session session) throws IOException {
log.info("ROOM {}: adding participant {}", roomName, name);
Participant participant = new Participant(name, session, this.pipeline);
joinRoom(participant);
participants.put(name, participant);
return participant;
}
/**
* @param participant
* @throws IOException
*/
private Collection<String> joinRoom(Participant newParticipant)
throws IOException {
JsonObject newParticipantAnnouncement = new JsonObject();
newParticipantAnnouncement
.addProperty("name", newParticipant.getName());
List<String> participantsList = newArrayListWithExpectedSize(participants
.values().size());
log.debug(
"ROOM {}: notifying other participants of new participant {}",
roomName, newParticipant.getName());
for (Participant participant : participants.values()) {
try {
participant.getSession().sendNotification(
"newParticipantArrived", newParticipantAnnouncement);
} catch (IOException e) {
log.debug("ROOM {}: participant {} could not be notified",
roomName, participant.getName(), e);
}
participantsList.add(participant.getName());
}
return participantsList;
}
public void removeParticipant(String name) throws IOException {
String removedParticipantName;
try (Participant removedParticipant = participants.remove(name)) {
removedParticipantName = removedParticipant.getName();
}
log.debug("ROOM {}: notifying all users that {} is leaving the room",
this.roomName, name);
List<String> unnotifiedParticipants = newArrayListWithExpectedSize(participants
.values().size());
JsonObject participantLeftNotification = new JsonObject();
participantLeftNotification.addProperty("name", removedParticipantName);
for (Participant participant : participants.values()) {
try {
participant.cancelVideoFrom(removedParticipantName);
participant.getSession().sendNotification("participantLeft",
participantLeftNotification);
} catch (IOException e) {
unnotifiedParticipants.add(participant.getName());
}
}
if (!unnotifiedParticipants.isEmpty()) {
// TODO send the list to the client? Doesn't seem useful
log.debug(
"ROOM {}: The users {} could not be notified that {} left the room",
this.roomName, unnotifiedParticipants, name);
}
}
/**
* @return a collection with all the participants in the room
*/
public Collection<Participant> getParticipants() {
return participants.values();
}
/**
* @param name
* @return the participant from this session
*/
public Participant getParticipant(String name) {
return participants.get(name);
}
}