- add sessionId in user info so we know if user is connected using Red5 or NodeJS

This commit is contained in:
Richard Alam 2015-01-23 20:00:13 +00:00
parent ee7731626b
commit 5798f727c5
11 changed files with 142 additions and 70 deletions

View File

@ -43,7 +43,8 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
private ConnectionInvokerService connInvokerService;
private IBigBlueButtonInGW bbbGW;
private static final String APP = "BBB";
private final String APP = "BBB";
private final String CONN = "RED5-";
@Override
public boolean appConnect(IConnection conn, Object[] params) {
@ -147,16 +148,17 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
log.debug("User [{}] connected to room [{}]", debugInfo, room);
bbbGW.initLockSettings(room, locked, lsMap);
connInvokerService.addConnection(bbbSession.getInternalUserID(), connection);
String meetingId = bbbSession.getRoom();
String userId = bbbSession.getInternalUserID();
String connType = getConnectionType(Red5.getConnectionLocal().getType());
String userFullname = bbbSession.getUsername();
String connId = Red5.getConnectionLocal().getSessionId();
String meetingId = bbbSession.getRoom();
String userId = bbbSession.getInternalUserID();
String connType = getConnectionType(Red5.getConnectionLocal().getType());
String userFullname = bbbSession.getUsername();
String connId = Red5.getConnectionLocal().getSessionId();
String sessionId = CONN + connId + "-" + userId;
connInvokerService.addConnection(sessionId, connection);
log.info("User connected: sessionId=[" + connId + "], encoding=[" + connType +
log.info("User connected: sessionId=[" + sessionId + "], encoding=[" + connType +
"], meetingId= [" + meetingId
+ "], userId=[" + userId + "] username=[" + userFullname +"]");
@ -166,14 +168,15 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
logData.put("connType", connType);
logData.put("connId", connId);
logData.put("userId", userId);
logData.put("sessionId", sessionId);
logData.put("username", userFullname);
logData.put("event", "user_joining_bbb_apps");
logData.put("description", "User joining BBB Apps.");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
String logStr = gson.toJson(logData);
log.info("User joining bbbb-aps: data={}", logStr);
log.info("User joining bbb-aaps: data={}", logStr);
return super.roomConnect(connection, params);
@ -196,40 +199,67 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
int remotePort = Red5.getConnectionLocal().getRemotePort();
String clientId = Red5.getConnectionLocal().getClient().getId();
log.info("***** " + APP + "[clientid=" + clientId + "] disconnnected from " + remoteHost + ":" + remotePort + ".");
connInvokerService.removeConnection(getBbbSession().getInternalUserID());
BigBlueButtonSession bbbSession = (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION);
String meetingId = bbbSession.getRoom();
String userId = bbbSession.getInternalUserID();
String connType = getConnectionType(Red5.getConnectionLocal().getType());
String userFullname = bbbSession.getUsername();
String connId = Red5.getConnectionLocal().getSessionId();
log.info("User disconnected: sessionId=[" + connId + "], encoding=[" + connType +
"], meetingId= [" + meetingId + "], userId=[" + userId + "] username=[" + userFullname +"]");
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId);
logData.put("connType", connType);
logData.put("connId", connId);
logData.put("userId", userId);
logData.put("username", userFullname);
logData.put("event", "user_leaving_bbb_apps");
logData.put("description", "User leaving BBB Apps.");
bbbGW.userLeft(bbbSession.getRoom(), getBbbSession().getInternalUserID());
BigBlueButtonSession bbbSession = (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION);
String meetingId = bbbSession.getRoom();
String userId = bbbSession.getInternalUserID();
String connType = getConnectionType(Red5.getConnectionLocal().getType());
String userFullname = bbbSession.getUsername();
String connId = Red5.getConnectionLocal().getSessionId();
String sessionId = CONN + connId + "-" + userId;
log.info("User disconnected: sessionId=[" + sessionId + "], encoding=[" + connType +
"], meetingId= [" + meetingId + "], userId=[" + userId + "] username=[" + userFullname +"]");
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId);
logData.put("connType", connType);
logData.put("connId", connId);
logData.put("sessionId", sessionId);
logData.put("userId", userId);
logData.put("username", userFullname);
logData.put("event", "user_leaving_bbb_apps");
logData.put("description", "User leaving BBB Apps.");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.info("User leaving bbb-apps: data={}", logStr);
connInvokerService.removeConnection(sessionId);
bbbGW.userLeft(bbbSession.getRoom(), getBbbSession().getInternalUserID(), sessionId);
super.roomDisconnect(conn);
}
public void validateToken(String token) {
public void validateToken(Map<String, String> msg) {
// String userId = (String) msg.get("userId");
String token = (String) msg.get("authToken");
BigBlueButtonSession bbbSession = (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION);
assert bbbSession != null;
String userId = bbbSession.getInternalUserID();
String meetingId = Red5.getConnectionLocal().getScope().getName();
bbbGW.validateAuthToken(meetingId, userId, token, meetingId + "/" + userId);
String connId = Red5.getConnectionLocal().getSessionId();
String sessionId = CONN + connId + "-" + userId;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId);
logData.put("connId", connId);
logData.put("sessionId", sessionId);
logData.put("userId", userId);
logData.put("token", token);
logData.put("event", "user_validate_token_bbb_apps");
logData.put("description", "User validate token BBB Apps.");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.info("User validate token bbb-apps: data={}", logStr);
bbbGW.validateAuthToken(meetingId, userId, token, meetingId + "/" + userId, sessionId);
}
public void joinMeeting(String userId) {
@ -240,8 +270,24 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
String role = bbbSession.getRole();
String meetingId = bbbSession.getRoom();
log.debug(APP + ":joinMeeting - [" + meetingId + "] [" + userid + ", " + username + ", " + role + "]");
bbbGW.userJoin(meetingId, userid);
String connId = Red5.getConnectionLocal().getSessionId();
String sessionId = CONN + connId + "-" + userId;
Map<String, Object> logData = new HashMap<String, Object>();
logData.put("meetingId", meetingId);
logData.put("connId", connId);
logData.put("userId", userId);
logData.put("sessionId", sessionId);
logData.put("username", username);
logData.put("event", "user_join_bbb_apps");
logData.put("description", "User join BBB Apps.");
Gson gson = new Gson();
String logStr = gson.toJson(logData);
log.info("User join bbb-aaps: data={}", logStr);
bbbGW.userJoin(meetingId, userid, sessionId);
}
}

View File

@ -54,7 +54,9 @@ public class MeetingMessageHandler implements MessageHandler {
} else if (msg instanceof ValidateAuthTokenMessage) {
ValidateAuthTokenMessage emm = (ValidateAuthTokenMessage) msg;
log.info("Received ValidateAuthTokenMessage token request. Meeting id [{}]", emm.meetingId);
bbbGW.validateAuthToken(emm.meetingId, emm.userId, emm.token, emm.replyTo);
log.warn("TODO: Need to pass sessionId on ValidateAuthTokenMessage message.");
String sessionId = "tobeimplemented";
bbbGW.validateAuthToken(emm.meetingId, emm.userId, emm.token, emm.replyTo, sessionId);
} else if (msg instanceof UserConnectedToGlobalAudio) {
UserConnectedToGlobalAudio emm = (UserConnectedToGlobalAudio) msg;

View File

@ -46,8 +46,9 @@ public class MessageFromJsonConverter {
String userid = payload.get(Constants.USER_ID).getAsString();
String authToken = payload.get(Constants.AUTH_TOKEN).getAsString();
String replyTo = header.get(Constants.REPLY_TO).getAsString();
return new ValidateAuthTokenMessage(id, userid, authToken, replyTo);
String sessionId = "tobeimplemented";
return new ValidateAuthTokenMessage(id, userid, authToken, replyTo,
sessionId);
}
private static IMessage processCreateMeeting(JsonObject payload) {

View File

@ -8,11 +8,13 @@ public class ValidateAuthTokenMessage implements IMessage {
public final String userId;
public final String token;
public final String replyTo;
public final String sessionId;
public ValidateAuthTokenMessage(String meetingId, String userId, String token, String replyTo) {
public ValidateAuthTokenMessage(String meetingId, String userId, String token, String replyTo, String sessionId) {
this.meetingId = meetingId;
this.userId = userId;
this.token = token;
this.replyTo = replyTo;
this.replyTo = replyTo;
this.sessionId = sessionId;
}
}

View File

@ -2,16 +2,21 @@
package org.bigbluebutton.conference.service.participants;
import org.bigbluebutton.conference.BigBlueButtonApplication;
import org.bigbluebutton.conference.service.messaging.MessagingConstants;
import org.bigbluebutton.conference.service.messaging.redis.MessageHandler;
//import org.bigbluebutton.core.api.*;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
public class ParticipantsListener implements MessageHandler{
private static Logger log = Red5LoggerFactory.getLogger(BigBlueButtonApplication.class, "bigbluebutton");
private IBigBlueButtonInGW bbbInGW;
public void setBigBlueButtonInGW(IBigBlueButtonInGW bbbInGW) {
@ -37,7 +42,12 @@ public class ParticipantsListener implements MessageHandler{
String userID = payloadObject.get("userid").toString().replace("\"", "");
if(eventName.equalsIgnoreCase("user_leaving_request")){
bbbInGW.userLeft(roomName, userID);
/**
* TODO: HTML5 client need to pass this parameter. (ralam jan 22, 2015)
*/
log.warn("TODO: Need to pass sessionId on user_leaving_request message.");
String sessionId = "tobeimplemented";
bbbInGW.userLeft(roomName, userID, sessionId);
}
else if(eventName.equalsIgnoreCase("user_raised_hand_message")){
bbbInGW.userRaiseHand(roomName, userID);

View File

@ -28,7 +28,7 @@ public interface IBigBlueButtonInGW {
// Users
void validateAuthToken(String meetingId, String userId, String token, String correlationId);
void validateAuthToken(String meetingId, String userId, String token, String correlationId, String sessionId);
void registerUser(String roomName, String userid, String username, String role, String externUserID, String authToken);
void userRaiseHand(String meetingId, String userId);
void lowerHand(String meetingId, String userId, String loweredBy);
@ -36,8 +36,8 @@ public interface IBigBlueButtonInGW {
void unshareWebcam(String meetingId, String userId);
void setUserStatus(String meetingID, String userID, String status, Object value);
void getUsers(String meetingID, String requesterID);
void userLeft(String meetingID, String userID);
void userJoin(String meetingID, String userID);
void userLeft(String meetingID, String userID, String sessionId);
void userJoin(String meetingID, String userID, String sessionId);
void getCurrentPresenter(String meetingID, String requesterID);
void assignPresenter(String meetingID, String newPresenterID, String newPresenterName, String assignedBy);
void setRecordingStatus(String meetingId, String userId, Boolean recording);

View File

@ -61,9 +61,9 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway, presUtil: PreuploadedPresen
/*************************************************************
* Message Interface for Users
*************************************************************/
def validateAuthToken(meetingId: String, userId: String, token: String, correlationId: String) {
def validateAuthToken(meetingId: String, userId: String, token: String, correlationId: String, sessionId: String) {
// println("******************** VALIDATE TOKEN [" + token + "] ***************************** ")
bbbGW.accept(new ValidateAuthToken(meetingId, userId, token, correlationId))
bbbGW.accept(new ValidateAuthToken(meetingId, userId, token, correlationId, sessionId))
}
def registerUser(meetingID: String, userID: String, name: String, role: String, extUserID: String, authToken: String):Unit = {
@ -165,12 +165,12 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway, presUtil: PreuploadedPresen
bbbGW.accept(new GetUsers(meetingID, requesterID))
}
def userLeft(meetingID: String, userID: String):Unit = {
bbbGW.accept(new UserLeaving(meetingID, userID))
def userLeft(meetingID: String, userID: String, sessionId: String):Unit = {
bbbGW.accept(new UserLeaving(meetingID, userID, sessionId))
}
def userJoin(meetingID: String, userID: String):Unit = {
bbbGW.accept(new UserJoining(meetingID, userID))
def userJoin(meetingID: String, userID: String, sessionId: String):Unit = {
bbbGW.accept(new UserJoining(meetingID, userID, sessionId))
}
def assignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String):Unit = {

View File

@ -80,7 +80,8 @@ case class ValidateAuthToken(
meetingID: String,
userId: String,
token: String,
correlationId: String) extends InMessage
correlationId: String,
sessionId: String) extends InMessage
case class RegisterUser(
meetingID: String,
@ -93,12 +94,14 @@ case class RegisterUser(
case class UserJoining(
meetingID: String,
userID: String
userID: String,
sessionId: String
) extends InMessage
case class UserLeaving(
meetingID: String,
userID: String
userID: String,
sessionId: String
) extends InMessage
case class GetUsers(

View File

@ -59,6 +59,7 @@ case class Voice(
)
case class UserVO(
sessionId: String,
userID: String,
externUserID: String,
name: String,

View File

@ -73,7 +73,7 @@ trait UsersApp {
def handleValidateAuthToken(msg: ValidateAuthToken) {
// println("*************** Got ValidateAuthToken message ********************" )
regUsers.get (msg.userId) match {
regUsers.get (msg.token) match {
case Some(u) =>
{
val replyTo = meetingID + '/' + msg.userId
@ -88,7 +88,7 @@ trait UsersApp {
this ! (new GetChatHistoryRequest(meetingID, msg.userId, replyTo))
//join the user
handleUserJoin(new UserJoining(meetingID, msg.userId))
handleUserJoin(new UserJoining(meetingID, msg.userId, msg.sessionId))
//send the presentation
logger.info("ValidateToken success: mid=[" + meetingID + "] uid=[" + msg.userId + "]")
@ -108,7 +108,7 @@ trait UsersApp {
sendMeetingHasEnded(msg.userID)
} else {
val regUser = new RegisteredUser(msg.userID, msg.extUserID, msg.name, msg.role, msg.authToken)
regUsers += msg.userID -> regUser
regUsers += msg.authToken -> regUser
logger.info("Register user success: mid=[" + meetingID + "] uid=[" + msg.userID + "]")
outGW.send(new UserRegistered(meetingID, recorded, regUser))
}
@ -276,7 +276,7 @@ trait UsersApp {
regUser foreach { ru =>
val vu = new VoiceUser(msg.userID, msg.userID, ru.name, ru.name,
false, false, false, false)
val uvo = new UserVO(msg.userID, ru.externId, ru.name,
val uvo = new UserVO(msg.sessionId, msg.userID, ru.externId, ru.name,
ru.role, raiseHand=false, presenter=false,
hasStream=false, locked=false, webcamStream="",
phoneUser=false, vu, listenOnly=false, permissions)
@ -300,20 +300,20 @@ trait UsersApp {
}
def handleUserLeft(msg: UserLeaving):Unit = {
if (users.hasUser(msg.userID)) {
if (users.hasUser(msg.userID)) {
val user = users.removeUser(msg.userID)
user foreach { u =>
logger.info("User left meeting: mid=[" + meetingID + "] uid=[" + u.userID + "]")
outGW.send(new UserLeft(msg.meetingID, recorded, u))
}
startCheckingIfWeNeedToEndVoiceConf()
stopAutoStartedRecording()
}
startCheckingIfWeNeedToEndVoiceConf()
stopAutoStartedRecording()
}
}
def handleUserJoinedVoiceFromPhone(msg: VoiceUserJoined) = {
val user = users.getUserWithVoiceUserId(msg.voiceUser.userId) match {
val user = users.getUserWithVoiceUserId(msg.voiceUser.userId) match {
case Some(user) => {
logger.info("Voice user=[" + msg.voiceUser.userId + "] is already in conf=[" + voiceBridge + "]. Must be duplicate message.")
}
@ -325,7 +325,10 @@ trait UsersApp {
val vu = new VoiceUser(msg.voiceUser.userId, webUserId,
msg.voiceUser.callerName, msg.voiceUser.callerNum,
true, false, false, false)
val uvo = new UserVO(webUserId, webUserId, msg.voiceUser.callerName,
val sessionId = "PHONE-" + webUserId;
val uvo = new UserVO(sessionId, webUserId, webUserId, msg.voiceUser.callerName,
Role.VIEWER, raiseHand=false, presenter=false,
hasStream=false, locked=false, webcamStream="",
phoneUser=true, vu, listenOnly=false, permissions)
@ -339,7 +342,7 @@ trait UsersApp {
outGW.send(new MuteVoiceUser(meetingID, recorded, uvo.userID, uvo.userID, meetingMuted))
}
}
}
}
def handleVoiceUserJoined(msg: VoiceUserJoined) = {

View File

@ -26,7 +26,11 @@ class UsersModel {
user
}
def hasSessionId(sessionId: String):Boolean = {
uservos.contains(sessionId)
}
def hasUser(userID: String):Boolean = {
uservos.contains(userID)
}