Merge branch 'pedrobmarin-reconnect-fixes'
This commit is contained in:
commit
73d00517cf
@ -26,11 +26,13 @@ trait UsersApp {
|
||||
|
||||
val user = usersModel.getUser(msg.userid)
|
||||
user foreach { u =>
|
||||
val vu = u.voiceUser.copy(joined = false, talking = false)
|
||||
val uvo = u.copy(listenOnly = true, voiceUser = vu)
|
||||
usersModel.addUser(uvo)
|
||||
log.info("UserConnectedToGlobalAudio: meetingId=" + mProps.meetingID + " userId=" + uvo.userID + " user=" + uvo)
|
||||
outGW.send(new UserListeningOnly(mProps.meetingID, mProps.recorded, uvo.userID, uvo.listenOnly))
|
||||
if (usersModel.addGlobalAudioConnection(msg.userid)) {
|
||||
val vu = u.voiceUser.copy(joined = false, talking = false)
|
||||
val uvo = u.copy(listenOnly = true, voiceUser = vu)
|
||||
usersModel.addUser(uvo)
|
||||
log.info("UserConnectedToGlobalAudio: meetingId=" + mProps.meetingID + " userId=" + uvo.userID + " user=" + uvo)
|
||||
outGW.send(new UserListeningOnly(mProps.meetingID, mProps.recorded, uvo.userID, uvo.listenOnly))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,16 +41,18 @@ trait UsersApp {
|
||||
|
||||
val user = usersModel.getUser(msg.userid)
|
||||
user foreach { u =>
|
||||
if (!u.joinedWeb) {
|
||||
val userLeaving = usersModel.removeUser(u.userID)
|
||||
log.info("Not web user. Send user left message. meetingId=" + mProps.meetingID + " userId=" + u.userID + " user=" + u)
|
||||
userLeaving foreach (u => outGW.send(new UserLeft(mProps.meetingID, mProps.recorded, u)))
|
||||
} else {
|
||||
val vu = u.voiceUser.copy(joined = false)
|
||||
val uvo = u.copy(listenOnly = false, voiceUser = vu)
|
||||
usersModel.addUser(uvo)
|
||||
log.info("UserDisconnectedToGlobalAudio: meetingId=" + mProps.meetingID + " userId=" + uvo.userID + " user=" + uvo)
|
||||
outGW.send(new UserListeningOnly(mProps.meetingID, mProps.recorded, uvo.userID, uvo.listenOnly))
|
||||
if (usersModel.removeGlobalAudioConnection(msg.userid)) {
|
||||
if (!u.joinedWeb) {
|
||||
val userLeaving = usersModel.removeUser(u.userID)
|
||||
log.info("Not web user. Send user left message. meetingId=" + mProps.meetingID + " userId=" + u.userID + " user=" + u)
|
||||
userLeaving foreach (u => outGW.send(new UserLeft(mProps.meetingID, mProps.recorded, u)))
|
||||
} else {
|
||||
val vu = u.voiceUser.copy(joined = false)
|
||||
val uvo = u.copy(listenOnly = false, voiceUser = vu)
|
||||
usersModel.addUser(uvo)
|
||||
log.info("UserDisconnectedToGlobalAudio: meetingId=" + mProps.meetingID + " userId=" + uvo.userID + " user=" + uvo)
|
||||
outGW.send(new UserListeningOnly(mProps.meetingID, mProps.recorded, uvo.userID, uvo.listenOnly))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,12 @@ class UsersModel {
|
||||
|
||||
private var regUsers = new collection.immutable.HashMap[String, RegisteredUser]
|
||||
|
||||
/* When reconnecting SIP global audio, users may receive the connection message
|
||||
* before the disconnection message.
|
||||
* This variable is a connection counter that should control this scenario.
|
||||
*/
|
||||
private var globalAudioConnectionCounter = new collection.immutable.HashMap[String, Integer]
|
||||
|
||||
private var locked = false
|
||||
private var meetingMuted = false
|
||||
|
||||
@ -144,4 +150,34 @@ class UsersModel {
|
||||
case None =>
|
||||
}
|
||||
}
|
||||
|
||||
def addGlobalAudioConnection(userID: String): Boolean = {
|
||||
globalAudioConnectionCounter.get(userID) match {
|
||||
case Some(vc) => {
|
||||
globalAudioConnectionCounter += userID -> (vc + 1)
|
||||
false
|
||||
}
|
||||
case None => {
|
||||
globalAudioConnectionCounter += userID -> 1
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def removeGlobalAudioConnection(userID: String): Boolean = {
|
||||
globalAudioConnectionCounter.get(userID) match {
|
||||
case Some(vc) => {
|
||||
if (vc == 1) {
|
||||
globalAudioConnectionCounter -= userID
|
||||
true
|
||||
} else {
|
||||
globalAudioConnectionCounter += userID -> (vc - 1)
|
||||
false
|
||||
}
|
||||
}
|
||||
case None => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -133,6 +133,7 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
|
||||
connection.setAttribute(Constants.SESSION, bbbSession);
|
||||
connection.setAttribute("INTERNAL_USER_ID", internalUserID);
|
||||
connection.setAttribute("USER_SESSION_ID", sessionId);
|
||||
connection.setAttribute("TIMESTAMP", System.currentTimeMillis());
|
||||
|
||||
red5InGW.initLockSettings(room, lsMap);
|
||||
|
||||
|
@ -21,6 +21,7 @@ package org.bigbluebutton.red5.client.messaging;
|
||||
import java.util.Set;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
@ -274,15 +275,31 @@ public class ConnectionInvokerService {
|
||||
}
|
||||
|
||||
private IConnection getConnection(IScope scope, String userID) {
|
||||
Set<IConnection> conns = scope.getClientConnections();
|
||||
for (IConnection conn : conns) {
|
||||
Set<IConnection> conns = new HashSet<IConnection>();
|
||||
for (IConnection conn : scope.getClientConnections()) {
|
||||
String connID = (String) conn.getAttribute("USER_SESSION_ID");
|
||||
if (connID != null && connID.equals(userID)) {
|
||||
return conn;
|
||||
conns.add(conn);
|
||||
}
|
||||
}
|
||||
log.warn("Failed to get connection for userId = " + userID);
|
||||
return null;
|
||||
if (!conns.isEmpty()) {
|
||||
return getLastConnection(conns);
|
||||
} else {
|
||||
log.warn("Failed to get connection for userId = " + userID);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private IConnection getLastConnection(Set<IConnection> conns) {
|
||||
IConnection conn = null;
|
||||
for (IConnection c : conns) {
|
||||
if (conn == null) {
|
||||
conn = c;
|
||||
} else if ((long) conn.getAttribute("TIMESTAMP") < (long) c.getAttribute("TIMESTAMP")) {
|
||||
conn = c;
|
||||
}
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
public IScope getScope(String meetingID) {
|
||||
|
@ -53,6 +53,7 @@ package org.bigbluebutton.modules.phone.managers {
|
||||
private var closedByUser:Boolean = false;
|
||||
|
||||
private var reconnecting:Boolean = false;
|
||||
private var amIListenOnly:Boolean = false;
|
||||
|
||||
private var dispatcher:Dispatcher;
|
||||
|
||||
@ -83,19 +84,24 @@ package org.bigbluebutton.modules.phone.managers {
|
||||
}
|
||||
|
||||
public function connect():void {
|
||||
closedByUser = false;
|
||||
var isTunnelling:Boolean = BBB.initConnectionManager().isTunnelling;
|
||||
if (isTunnelling) {
|
||||
uri = uri.replace(/rtmp:/gi, "rtmpt:");
|
||||
}
|
||||
LOGGER.debug("Connecting to uri=[{0}]", [uri]);
|
||||
NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
|
||||
netConnection = new NetConnection();
|
||||
netConnection.proxyType = "best";
|
||||
netConnection.client = this;
|
||||
netConnection.addEventListener( NetStatusEvent.NET_STATUS , netStatus );
|
||||
netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
|
||||
netConnection.connect(uri, meetingId, externUserId, username);
|
||||
if (!reconnecting || amIListenOnly) {
|
||||
closedByUser = false;
|
||||
var isTunnelling:Boolean = BBB.initConnectionManager().isTunnelling;
|
||||
if (isTunnelling) {
|
||||
uri = uri.replace(/rtmp:/gi, "rtmpt:");
|
||||
}
|
||||
LOGGER.debug("Connecting to uri=[{0}]", [uri]);
|
||||
NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
|
||||
netConnection = new NetConnection();
|
||||
netConnection.proxyType = "best";
|
||||
netConnection.client = this;
|
||||
netConnection.addEventListener( NetStatusEvent.NET_STATUS , netStatus );
|
||||
netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
|
||||
netConnection.connect(uri, meetingId, externUserId, username);
|
||||
}
|
||||
if (reconnecting && !amIListenOnly) {
|
||||
handleConnectionSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
public function disconnect(requestByUser:Boolean):void {
|
||||
@ -134,7 +140,7 @@ package org.bigbluebutton.modules.phone.managers {
|
||||
disconnectedEvent.payload.callbackParameters = [];
|
||||
dispatcher.dispatchEvent(disconnectedEvent);
|
||||
|
||||
dispatcher.dispatchEvent(new FlashVoiceConnectionStatusEvent(FlashVoiceConnectionStatusEvent.DISCONNECTED));
|
||||
dispatcher.dispatchEvent(new FlashVoiceConnectionStatusEvent(FlashVoiceConnectionStatusEvent.DISCONNECTED, reconnecting));
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,12 +218,14 @@ package org.bigbluebutton.modules.phone.managers {
|
||||
//
|
||||
//********************************************************************************************
|
||||
public function doCall(dialStr:String, listenOnly:Boolean = false):void {
|
||||
amIListenOnly = listenOnly;
|
||||
LOGGER.debug("in doCall - Calling {0} {1}", [dialStr, listenOnly? "*listen only*": ""]);
|
||||
netConnection.call("voiceconf.call", null, "default", username, dialStr, listenOnly.toString());
|
||||
}
|
||||
|
||||
public function doHangUp():void {
|
||||
if (isConnected()) {
|
||||
amIListenOnly = false;
|
||||
LOGGER.debug("hanging up call");
|
||||
netConnection.call("voiceconf.hangup", null, "default");
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
import org.as3commons.logging.util.jsonXify;
|
||||
import org.bigbluebutton.common.Media;
|
||||
import org.bigbluebutton.core.UsersUtil;
|
||||
import org.bigbluebutton.core.events.VoiceConfEvent;
|
||||
import org.bigbluebutton.main.api.JSLog;
|
||||
import org.bigbluebutton.modules.phone.PhoneOptions;
|
||||
import org.bigbluebutton.modules.phone.events.FlashCallConnectedEvent;
|
||||
@ -453,5 +454,13 @@
|
||||
connectionManager.disconnect(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function handleReconnectSIPSucceededEvent():void {
|
||||
if (state != ON_LISTEN_ONLY_STREAM) {
|
||||
var e:VoiceConfEvent = new VoiceConfEvent(VoiceConfEvent.EJECT_USER);
|
||||
e.userid = UsersUtil.getMyUserID();
|
||||
dispatcher.dispatchEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
import mx.events.FlexEvent;
|
||||
|
||||
import org.bigbluebutton.main.events.MadePresenterEvent;
|
||||
import org.bigbluebutton.main.events.BBBEvent;
|
||||
import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
|
||||
import org.bigbluebutton.modules.phone.events.FlashCallConnectedEvent;
|
||||
import org.bigbluebutton.modules.phone.events.FlashCallDisconnectedEvent;
|
||||
@ -119,4 +120,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}">
|
||||
<MethodInvoker generator="{FlashCallManager}" method="handleBecomeViewer"/>
|
||||
</EventHandlers>
|
||||
|
||||
<EventHandlers type="{BBBEvent.RECONNECT_SIP_SUCCEEDED_EVENT}">
|
||||
<MethodInvoker generator="{FlashCallManager}" method="handleReconnectSIPSucceededEvent"/>
|
||||
</EventHandlers>
|
||||
</EventMap>
|
||||
|
Loading…
Reference in New Issue
Block a user