Merge branch 'master' of github.com:bigbluebutton/bigbluebutton into webrtc-desktop-share-merging
This commit is contained in:
commit
eb57aa7da1
@ -48,12 +48,11 @@ libraryDependencies ++= {
|
||||
"commons-codec" % "commons-codec" % "1.8",
|
||||
"joda-time" % "joda-time" % "2.3",
|
||||
"com.google.code.gson" % "gson" % "1.7.1",
|
||||
"redis.clients" % "jedis" % "2.1.0",
|
||||
"redis.clients" % "jedis" % "2.7.2",
|
||||
"org.apache.commons" % "commons-lang3" % "3.2",
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.12"
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.13"
|
||||
)}
|
||||
|
||||
|
||||
seq(Revolver.settings: _*)
|
||||
|
||||
scalariformSettings
|
||||
|
@ -2,6 +2,7 @@ package org.bigbluebutton.core.pubsub.receivers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bigbluebutton.common.messages.CreateMeetingMessage;
|
||||
import org.bigbluebutton.common.messages.DestroyMeetingMessage;
|
||||
import org.bigbluebutton.common.messages.EndMeetingMessage;
|
||||
@ -10,6 +11,7 @@ import org.bigbluebutton.common.messages.IBigBlueButtonMessage;
|
||||
import org.bigbluebutton.common.messages.KeepAliveMessage;
|
||||
import org.bigbluebutton.common.messages.MessageFromJsonConverter;
|
||||
import org.bigbluebutton.common.messages.MessagingConstants;
|
||||
import org.bigbluebutton.common.messages.PubSubPingMessage;
|
||||
import org.bigbluebutton.common.messages.RegisterUserMessage;
|
||||
import org.bigbluebutton.common.messages.UserConnectedToGlobalAudio;
|
||||
import org.bigbluebutton.common.messages.UserDisconnectedFromGlobalAudio;
|
||||
@ -19,6 +21,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public class MeetingMessageReceiver implements MessageHandler {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(MeetingMessageReceiver.class);
|
||||
@ -96,16 +100,32 @@ public class MeetingMessageReceiver implements MessageHandler {
|
||||
System.out.println("Failed to decode message: [" + message + "]");
|
||||
}
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.TO_SYSTEM_CHANNEL)) {
|
||||
IBigBlueButtonMessage msg = MessageFromJsonConverter.convert(message);
|
||||
|
||||
if (msg != null) {
|
||||
if (msg instanceof KeepAliveMessage) {
|
||||
KeepAliveMessage emm = (KeepAliveMessage) msg;
|
||||
bbbGW.isAliveAudit(emm.keepAliveId);
|
||||
}
|
||||
} else {
|
||||
System.out.println("Unknown message: [" + message + "]");
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject obj = (JsonObject) parser.parse(message);
|
||||
|
||||
if (obj.has("header") && obj.has("payload")) {
|
||||
JsonObject header = (JsonObject) obj.get("header");
|
||||
if (header.has("name")) {
|
||||
String messageName = header.get("name").getAsString();
|
||||
if (PubSubPingMessage.PUBSUB_PING.equals(messageName)){
|
||||
Gson gson = new Gson();
|
||||
PubSubPingMessage msg = gson.fromJson(message, PubSubPingMessage.class);
|
||||
bbbGW.handleBigBlueButtonMessage(msg);
|
||||
} else {
|
||||
IBigBlueButtonMessage msg = MessageFromJsonConverter.convert(message);
|
||||
|
||||
if (msg != null) {
|
||||
if (msg instanceof KeepAliveMessage) {
|
||||
KeepAliveMessage emm = (KeepAliveMessage) msg;
|
||||
bbbGW.isAliveAudit(emm.keepAliveId);
|
||||
}
|
||||
} else {
|
||||
System.out.println("Unknown message: [" + message + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,142 +0,0 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.bigbluebutton.core.service.recorder;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
|
||||
public class GenericObjectPoolConfigWrapper {
|
||||
|
||||
private final GenericObjectPool.Config config;
|
||||
|
||||
public GenericObjectPoolConfigWrapper() {
|
||||
this.config = new GenericObjectPool.Config();
|
||||
}
|
||||
|
||||
public GenericObjectPool.Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public int getMaxIdle() {
|
||||
return this.config.maxIdle;
|
||||
}
|
||||
|
||||
public void setMaxIdle(int maxIdle) {
|
||||
this.config.maxIdle = maxIdle;
|
||||
}
|
||||
|
||||
public int getMinIdle() {
|
||||
return this.config.minIdle;
|
||||
}
|
||||
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.config.minIdle = minIdle;
|
||||
}
|
||||
|
||||
public int getMaxActive() {
|
||||
return this.config.maxActive;
|
||||
}
|
||||
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.config.maxActive = maxActive;
|
||||
}
|
||||
|
||||
public long getMaxWait() {
|
||||
return this.config.maxWait;
|
||||
}
|
||||
|
||||
public void setMaxWait(long maxWait) {
|
||||
this.config.maxWait = maxWait;
|
||||
}
|
||||
|
||||
public byte getWhenExhaustedAction() {
|
||||
return this.config.whenExhaustedAction;
|
||||
}
|
||||
|
||||
public void setWhenExhaustedAction(byte whenExhaustedAction) {
|
||||
this.config.whenExhaustedAction = whenExhaustedAction;
|
||||
}
|
||||
|
||||
public boolean isTestOnBorrow() {
|
||||
return this.config.testOnBorrow;
|
||||
}
|
||||
|
||||
public void setTestOnBorrow(boolean testOnBorrow) {
|
||||
this.config.testOnBorrow = testOnBorrow;
|
||||
}
|
||||
|
||||
public boolean isTestOnReturn() {
|
||||
return this.config.testOnReturn;
|
||||
}
|
||||
|
||||
public void setTestOnReturn(boolean testOnReturn) {
|
||||
this.config.testOnReturn = testOnReturn;
|
||||
}
|
||||
|
||||
public boolean isTestWhileIdle() {
|
||||
return this.config.testWhileIdle;
|
||||
}
|
||||
|
||||
public void setTestWhileIdle(boolean testWhileIdle) {
|
||||
this.config.testWhileIdle = testWhileIdle;
|
||||
}
|
||||
|
||||
public long getTimeBetweenEvictionRunsMillis() {
|
||||
return this.config.timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public void setTimeBetweenEvictionRunsMillis(
|
||||
long timeBetweenEvictionRunsMillis) {
|
||||
this.config.timeBetweenEvictionRunsMillis =
|
||||
timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public int getNumTestsPerEvictionRun() {
|
||||
return this.config.numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
|
||||
this.config.numTestsPerEvictionRun = numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
public long getMinEvictableIdleTimeMillis() {
|
||||
return this.config.minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
|
||||
this.config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public long getSoftMinEvictableIdleTimeMillis() {
|
||||
return this.config.softMinEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setSoftMinEvictableIdleTimeMillis(
|
||||
long softMinEvictableIdleTimeMillis) {
|
||||
this.config.softMinEvictableIdleTimeMillis =
|
||||
softMinEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public boolean isLifo() {
|
||||
return this.config.lifo;
|
||||
}
|
||||
|
||||
public void setLifo(boolean lifo) {
|
||||
this.config.lifo = lifo;
|
||||
}
|
||||
}
|
@ -18,20 +18,21 @@
|
||||
*/
|
||||
package org.bigbluebutton.core.service.recorder;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
public class RedisDispatcher implements Recorder {
|
||||
|
||||
private static final String COLON=":";
|
||||
private JedisPool redisPool;
|
||||
private GenericObjectPoolConfigWrapper config;
|
||||
|
||||
|
||||
public RedisDispatcher(String host, int port, String password) {
|
||||
setupConfig();
|
||||
redisPool = new JedisPool(config.getConfig(), host, port);
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
redisPool = new JedisPool(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null,
|
||||
Protocol.DEFAULT_DATABASE, "BbbAppsAkkaRec");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,22 +43,8 @@ public class RedisDispatcher implements Recorder {
|
||||
jedis.hmset("recording" + COLON + session + COLON + msgid, message.toMap());
|
||||
jedis.rpush("meeting" + COLON + session + COLON + "recordings", msgid.toString());
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupConfig() {
|
||||
config = new GenericObjectPoolConfigWrapper();
|
||||
config.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_FAIL);
|
||||
config.setMaxActive(12);
|
||||
config.setMaxIdle(6);
|
||||
config.setMinIdle(1);
|
||||
config.setTestOnBorrow(true);
|
||||
config.setTestOnReturn(true);
|
||||
config.setTestWhileIdle(true);
|
||||
config.setNumTestsPerEvictionRun(12);
|
||||
config.setTimeBetweenEvictionRunsMillis(60000);
|
||||
config.setMaxWait(5000);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class BigBlueButtonActor(val system: ActorSystem, recorderApp: RecorderApplicati
|
||||
case msg: CreateMeeting => handleCreateMeeting(msg)
|
||||
case msg: DestroyMeeting => handleDestroyMeeting(msg)
|
||||
case msg: KeepAliveMessage => handleKeepAliveMessage(msg)
|
||||
case msg: PubSubPing => handlePubSubPingMessage(msg)
|
||||
case msg: ValidateAuthToken => handleValidateAuthToken(msg)
|
||||
case msg: GetAllMeetingsRequest => handleGetAllMeetingsRequest(msg)
|
||||
case msg: UserJoinedVoiceConfMessage => handleUserJoinedVoiceConfMessage(msg)
|
||||
@ -180,6 +181,10 @@ class BigBlueButtonActor(val system: ActorSystem, recorderApp: RecorderApplicati
|
||||
outGW.send(new KeepAliveMessageReply(msg.aliveID))
|
||||
}
|
||||
|
||||
private def handlePubSubPingMessage(msg: PubSubPing): Unit = {
|
||||
outGW.send(new PubSubPong(msg.system, msg.timestamp))
|
||||
}
|
||||
|
||||
private def handleDestroyMeeting(msg: DestroyMeeting) {
|
||||
log.info("BBBActor received DestroyMeeting message for meeting id [" + msg.meetingID + "]")
|
||||
meetings.get(msg.meetingID) match {
|
||||
|
@ -15,8 +15,9 @@ import scala.concurrent.duration._
|
||||
import scala.util.Success
|
||||
import scala.util.Failure
|
||||
import org.bigbluebutton.core.service.recorder.RecorderApplication
|
||||
import org.bigbluebutton.common.messages.IBigBlueButtonMessage;
|
||||
import org.bigbluebutton.common.messages.IBigBlueButtonMessage
|
||||
import org.bigbluebutton.common.messages.StartCustomPollRequestMessage
|
||||
import org.bigbluebutton.common.messages.PubSubPingMessage
|
||||
|
||||
class BigBlueButtonInGW(val system: ActorSystem, recorderApp: RecorderApplication, messageSender: MessageSender,
|
||||
voiceEventRecorder: VoiceEventRecorder, val red5DeskShareIP: String, val red5DeskShareApp: String) extends IBigBlueButtonInGW {
|
||||
@ -29,6 +30,9 @@ class BigBlueButtonInGW(val system: ActorSystem, recorderApp: RecorderApplicatio
|
||||
case msg: StartCustomPollRequestMessage => {
|
||||
bbbActor ! new StartCustomPollRequest(msg.payload.meetingId, msg.payload.requesterId, msg.payload.pollType, msg.payload.answers)
|
||||
}
|
||||
case msg: PubSubPingMessage => {
|
||||
bbbActor ! new PubSubPing(msg.payload.system, msg.payload.timestamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@ import org.bigbluebutton.common.messages.GetCurrentLayoutReplyMessage
|
||||
import org.bigbluebutton.common.messages.BroadcastLayoutMessage
|
||||
import org.bigbluebutton.common.messages.LockLayoutMessage
|
||||
import org.bigbluebutton.core.pubsub.senders.WhiteboardMessageToJsonConverter
|
||||
import org.bigbluebutton.common.converters.ToJsonEncoder
|
||||
|
||||
object MessageSenderActor {
|
||||
def props(meetingId: String, msgSender: MessageSender): Props =
|
||||
@ -36,6 +37,8 @@ object MessageSenderActor {
|
||||
class MessageSenderActor(val meetingId: String, val service: MessageSender)
|
||||
extends Actor with ActorLogging {
|
||||
|
||||
val encoder = new ToJsonEncoder()
|
||||
|
||||
def receive = {
|
||||
case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg)
|
||||
case msg: SendPublicMessageEvent => handleSendPublicMessageEvent(msg)
|
||||
@ -49,6 +52,7 @@ class MessageSenderActor(val meetingId: String, val service: MessageSender)
|
||||
case msg: MeetingHasEnded => handleMeetingHasEnded(msg)
|
||||
case msg: MeetingDestroyed => handleMeetingDestroyed(msg)
|
||||
case msg: KeepAliveMessageReply => handleKeepAliveMessageReply(msg)
|
||||
case msg: PubSubPong => handlePubSubPong(msg)
|
||||
case msg: StartRecording => handleStartRecording(msg)
|
||||
case msg: StopRecording => handleStopRecording(msg)
|
||||
case msg: GetAllMeetingsReply => handleGetAllMeetingsReply(msg)
|
||||
@ -177,6 +181,11 @@ class MessageSenderActor(val meetingId: String, val service: MessageSender)
|
||||
service.send(MessagingConstants.FROM_MEETING_CHANNEL, json)
|
||||
}
|
||||
|
||||
private def handlePubSubPong(msg: PubSubPong) {
|
||||
val json = encoder.encodePubSubPongMessage(msg.system, msg.timestamp)
|
||||
service.send(MessagingConstants.FROM_SYSTEM_CHANNEL, json)
|
||||
}
|
||||
|
||||
private def handleKeepAliveMessageReply(msg: KeepAliveMessageReply) {
|
||||
val json = MeetingMessageToJsonConverter.keepAliveMessageReplyToJson(msg)
|
||||
service.send(MessagingConstants.FROM_SYSTEM_CHANNEL, json)
|
||||
|
@ -7,6 +7,8 @@ import org.bigbluebutton.core.MeetingProperties
|
||||
|
||||
trait InMessage { val meetingID: String }
|
||||
|
||||
case class PubSubPing(system: String, timestamp: Long)
|
||||
|
||||
case class IsMeetingActorAliveMessage(meetingId: String)
|
||||
case class KeepAliveMessage(aliveID: String)
|
||||
case class CreateMeeting(meetingID: String, mProps: MeetingProperties) extends InMessage
|
||||
|
@ -25,6 +25,7 @@ case class MeetingDestroyed(meetingID: String) extends IOutMessage
|
||||
case class DisconnectAllUsers(meetingID: String) extends IOutMessage
|
||||
case class DisconnectUser(meetingID: String, userId: String) extends IOutMessage
|
||||
case class KeepAliveMessageReply(aliveID: String) extends IOutMessage
|
||||
case class PubSubPong(system: String, timestamp: Long) extends IOutMessage
|
||||
case object IsAliveMessage extends IOutMessage
|
||||
|
||||
// Permissions
|
||||
|
@ -9,6 +9,7 @@ import akka.actor.ActorRef
|
||||
import akka.actor.actorRef2Scala
|
||||
import org.bigbluebutton.SystemConfiguration
|
||||
import org.bigbluebutton.core.pubsub.receivers.RedisMessageReceiver
|
||||
import redis.api.servers.ClientSetname
|
||||
|
||||
object AppsRedisSubscriberActor extends SystemConfiguration {
|
||||
|
||||
@ -28,6 +29,10 @@ class AppsRedisSubscriberActor(msgReceiver: RedisMessageReceiver, redisHost: Str
|
||||
new InetSocketAddress(redisHost, redisPort),
|
||||
channels, patterns) {
|
||||
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
write(ClientSetname("BbbAppsAkkaSub").encodedRequest)
|
||||
|
||||
def onMessage(message: Message) {
|
||||
log.error(s"SHOULD NOT BE RECEIVING: $message")
|
||||
}
|
||||
|
@ -13,20 +13,12 @@ class RedisPublisher(val system: ActorSystem) extends SystemConfiguration {
|
||||
|
||||
val redis = RedisClient(redisHost, redisPort)(system)
|
||||
|
||||
val futurePong = redis.ping()
|
||||
// println("Ping sent!")
|
||||
futurePong.map(pong => {
|
||||
// println(s"Redis replied with a $pong")
|
||||
})
|
||||
|
||||
Await.result(futurePong, 5 seconds)
|
||||
|
||||
// publish after 2 seconds every 2 or 5 seconds
|
||||
//system.scheduler.schedule(2 seconds, 2 seconds)(redis.publish("time", System.currentTimeMillis()))
|
||||
// system.scheduler.schedule(2 seconds, 5 seconds)(redis.publish("bigbluebutton:to-bbb-apps:users", "pattern value"))
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
redis.clientSetname("BbbAppsAkkaPub")
|
||||
|
||||
def publish(channel: String, data: String) {
|
||||
println("PUBLISH TO [" + channel + "]: \n [" + data + "]")
|
||||
// println("PUBLISH TO [" + channel + "]: \n [" + data + "]")
|
||||
redis.publish(channel, data)
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ libraryDependencies ++= {
|
||||
"com.google.code.gson" % "gson" % "1.7.1",
|
||||
"redis.clients" % "jedis" % "2.1.0",
|
||||
"org.apache.commons" % "commons-lang3" % "3.2",
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.12",
|
||||
"org.bigbluebutton" % "bbb-common-message" % "0.0.13",
|
||||
"org.bigbluebutton" % "bbb-fsesl-client" % "0.0.2"
|
||||
)}
|
||||
|
||||
|
@ -29,8 +29,6 @@ public class RedisMessageReceiver {
|
||||
}
|
||||
|
||||
public void handleMessage(String pattern, String channel, String message) {
|
||||
System.out.println("************* Received: \n" + message + "\n*************************");
|
||||
|
||||
if (channel.equalsIgnoreCase(TO_VOICE_CONF_SYSTEM_CHAN)) {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject obj = (JsonObject) parser.parse(message);
|
||||
|
@ -36,5 +36,5 @@ object Boot extends App with SystemConfiguration {
|
||||
|
||||
val redisMsgReceiver = new RedisMessageReceiver(fsApplication)
|
||||
|
||||
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(redisMsgReceiver), "redis-subscriber")
|
||||
val redisSubscriberActor = system.actorOf(AppsRedisSubscriberActor.props(system, redisMsgReceiver), "redis-subscriber")
|
||||
}
|
@ -9,32 +9,68 @@ import akka.actor.ActorRef
|
||||
import akka.actor.actorRef2Scala
|
||||
import org.bigbluebutton.SystemConfiguration
|
||||
import org.bigbluebutton.freeswitch.pubsub.receivers.RedisMessageReceiver
|
||||
import redis.api.servers.ClientSetname
|
||||
import org.bigbluebutton.common.converters.FromJsonDecoder
|
||||
import org.bigbluebutton.common.messages.PubSubPongMessage
|
||||
import akka.actor.ActorSystem
|
||||
import scala.concurrent.duration._
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
object AppsRedisSubscriberActor extends SystemConfiguration {
|
||||
|
||||
val channels = Seq("time")
|
||||
val patterns = Seq("bigbluebutton:to-voice-conf:*")
|
||||
val patterns = Seq("bigbluebutton:to-voice-conf:*", "bigbluebutton:from-bbb-apps:*")
|
||||
|
||||
def props(msgReceiver: RedisMessageReceiver): Props =
|
||||
Props(classOf[AppsRedisSubscriberActor], msgReceiver,
|
||||
def props(system: ActorSystem, msgReceiver: RedisMessageReceiver): Props =
|
||||
Props(classOf[AppsRedisSubscriberActor], system, msgReceiver,
|
||||
redisHost, redisPort,
|
||||
channels, patterns).withDispatcher("akka.rediscala-subscriber-worker-dispatcher")
|
||||
}
|
||||
|
||||
class AppsRedisSubscriberActor(msgReceiver: RedisMessageReceiver, redisHost: String,
|
||||
redisPort: Int,
|
||||
channels: Seq[String] = Nil, patterns: Seq[String] = Nil)
|
||||
extends RedisSubscriberActor(
|
||||
new InetSocketAddress(redisHost, redisPort),
|
||||
class AppsRedisSubscriberActor(val system: ActorSystem, msgReceiver: RedisMessageReceiver, redisHost: String,
|
||||
redisPort: Int, channels: Seq[String] = Nil, patterns: Seq[String] = Nil)
|
||||
extends RedisSubscriberActor(new InetSocketAddress(redisHost, redisPort),
|
||||
channels, patterns) {
|
||||
|
||||
val decoder = new FromJsonDecoder()
|
||||
|
||||
var lastPongReceivedOn = 0L
|
||||
system.scheduler.schedule(10 seconds, 10 seconds)(checkPongMessage())
|
||||
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
write(ClientSetname("BbbFsEslAkkaSub").encodedRequest)
|
||||
|
||||
def checkPongMessage() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
if (lastPongReceivedOn != 0 && (now - lastPongReceivedOn > 10000)) {
|
||||
log.error("FSESL pubsub error!");
|
||||
}
|
||||
}
|
||||
|
||||
def onMessage(message: Message) {
|
||||
log.debug(s"message received: $message")
|
||||
}
|
||||
|
||||
def onPMessage(pmessage: PMessage) {
|
||||
log.debug(s"pattern message received: $pmessage")
|
||||
msgReceiver.handleMessage(pmessage.patternMatched, pmessage.channel, pmessage.data)
|
||||
|
||||
val msg = decoder.decodeMessage(pmessage.data)
|
||||
|
||||
if (msg != null) {
|
||||
msg match {
|
||||
case m: PubSubPongMessage => {
|
||||
if (m.payload.system == "BbbFsESL") {
|
||||
lastPongReceivedOn = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
case _ => // do nothing
|
||||
}
|
||||
} else {
|
||||
msgReceiver.handleMessage(pmessage.patternMatched, pmessage.channel, pmessage.data)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def handleMessage(msg: String) {
|
||||
|
@ -8,22 +8,23 @@ import akka.actor.ActorSystem
|
||||
import scala.concurrent.Await
|
||||
import akka.actor.Actor
|
||||
import org.bigbluebutton.SystemConfiguration
|
||||
import org.bigbluebutton.common.converters.ToJsonEncoder
|
||||
|
||||
class RedisPublisher(val system: ActorSystem) extends SystemConfiguration {
|
||||
|
||||
val redis = RedisClient(redisHost, redisPort)(system)
|
||||
|
||||
val futurePong = redis.ping()
|
||||
println("Ping sent!")
|
||||
futurePong.map(pong => {
|
||||
println(s"Redis replied with a $pong")
|
||||
})
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
redis.clientSetname("BbbFsEslAkkaPub")
|
||||
|
||||
Await.result(futurePong, 5 seconds)
|
||||
val encoder = new ToJsonEncoder()
|
||||
def sendPingMessage() {
|
||||
val json = encoder.encodePubSubPingMessage("BbbFsESL", System.currentTimeMillis())
|
||||
redis.publish("bigbluebutton:to-bbb-apps:system", json)
|
||||
}
|
||||
|
||||
// publish after 2 seconds every 2 or 5 seconds
|
||||
//system.scheduler.schedule(2 seconds, 2 seconds)(redis.publish("time", System.currentTimeMillis()))
|
||||
// system.scheduler.schedule(2 seconds, 5 seconds)(redis.publish("bigbluebutton:to-bbb-apps:users", "pattern value"))
|
||||
system.scheduler.schedule(10 seconds, 10 seconds)(sendPingMessage())
|
||||
|
||||
def publish(channel: String, data: String) {
|
||||
println("PUBLISH TO [" + channel + "]: \n [" + data + "]")
|
||||
|
@ -4,7 +4,7 @@ name := "bbb-common-message"
|
||||
|
||||
organization := "org.bigbluebutton"
|
||||
|
||||
version := "0.0.12"
|
||||
version := "0.0.13"
|
||||
|
||||
// We want to have our jar files in lib_managed dir.
|
||||
// This way we'll have the right path when we import
|
||||
|
@ -0,0 +1,43 @@
|
||||
package org.bigbluebutton.common.converters;
|
||||
|
||||
import org.bigbluebutton.common.messages.IBigBlueButtonMessage;
|
||||
import org.bigbluebutton.common.messages.PubSubPingMessage;
|
||||
import org.bigbluebutton.common.messages.PubSubPongMessage;
|
||||
import org.bigbluebutton.common.messages.StartCustomPollRequestMessage;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public class FromJsonDecoder {
|
||||
|
||||
public IBigBlueButtonMessage decodeMessage(String message) {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject obj = (JsonObject) parser.parse(message);
|
||||
|
||||
if (obj.has("header") && obj.has("payload")) {
|
||||
JsonObject header = (JsonObject) obj.get("header");
|
||||
if (header.has("name")) {
|
||||
String messageName = header.get("name").getAsString();
|
||||
if (PubSubPingMessage.PUBSUB_PING.equals(messageName)){
|
||||
Gson gson = new Gson();
|
||||
PubSubPingMessage msg = gson.fromJson(message, PubSubPingMessage.class);
|
||||
return msg;
|
||||
}else if (PubSubPongMessage.PUBSUB_PONG.equals(messageName)){
|
||||
Gson gson = new Gson();
|
||||
PubSubPongMessage msg = gson.fromJson(message, PubSubPongMessage.class);
|
||||
return msg;
|
||||
} else if (StartCustomPollRequestMessage.START_CUSTOM_POLL_REQUEST.equals(messageName)){
|
||||
Gson gson = new Gson();
|
||||
StartCustomPollRequestMessage msg = gson.fromJson(message, StartCustomPollRequestMessage.class);
|
||||
return msg;
|
||||
} else {
|
||||
System.out.println("Unknown message name=[" + messageName + "]");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Invalid message format");
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package org.bigbluebutton.common.converters;
|
||||
|
||||
import org.bigbluebutton.common.messages.MessageHeader;
|
||||
import org.bigbluebutton.common.messages.PubSubPingMessage;
|
||||
import org.bigbluebutton.common.messages.PubSubPongMessage;
|
||||
import org.bigbluebutton.common.messages.payload.PubSubPingMessagePayload;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class ToJsonEncoder {
|
||||
|
||||
public String encodePubSubPongMessage(String system, Long timestamp) {
|
||||
PubSubPongMessage m = new PubSubPongMessage();
|
||||
MessageHeader header = new MessageHeader();
|
||||
PubSubPingMessagePayload payload = new PubSubPingMessagePayload();
|
||||
header.name = PubSubPongMessage.PUBSUB_PONG;
|
||||
header.timestamp = System.nanoTime();
|
||||
payload.system = system;
|
||||
payload.timestamp = timestamp;
|
||||
|
||||
m.header = header;
|
||||
m.payload = payload;
|
||||
Gson gson = new Gson();
|
||||
return gson.toJson(m);
|
||||
}
|
||||
|
||||
public String encodePubSubPingMessage(String system, Long timestamp) {
|
||||
PubSubPingMessage m = new PubSubPingMessage();
|
||||
MessageHeader header = new MessageHeader();
|
||||
PubSubPingMessagePayload payload = new PubSubPingMessagePayload();
|
||||
header.name = PubSubPingMessage.PUBSUB_PING;
|
||||
header.timestamp = System.nanoTime();
|
||||
payload.system = system;
|
||||
payload.timestamp = timestamp;
|
||||
|
||||
m.header = header;
|
||||
m.payload = payload;
|
||||
Gson gson = new Gson();
|
||||
return gson.toJson(m);
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.bigbluebutton.common.messages;
|
||||
|
||||
import org.bigbluebutton.common.messages.payload.PubSubPingMessagePayload;
|
||||
|
||||
public class PubSubPingMessage implements IBigBlueButtonMessage {
|
||||
|
||||
public static final String PUBSUB_PING = "BbbPubSubPingMessage";
|
||||
|
||||
public MessageHeader header;
|
||||
public PubSubPingMessagePayload payload;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package org.bigbluebutton.common.messages;
|
||||
|
||||
import org.bigbluebutton.common.messages.payload.PubSubPingMessagePayload;
|
||||
|
||||
public class PubSubPongMessage implements IBigBlueButtonMessage {
|
||||
|
||||
public static final String PUBSUB_PONG = "BbbPubSubPongMessage";
|
||||
|
||||
public MessageHeader header;
|
||||
public PubSubPingMessagePayload payload;
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package org.bigbluebutton.common.messages;
|
||||
|
||||
import org.bigbluebutton.common.messages.payload.StartCustomPollRequestMessagePayload;
|
||||
|
||||
public class StartCustomPollRequestMessage implements IBigBlueButtonMessage {
|
||||
|
||||
public static final String START_CUSTOM_POLL_REQUEST = "start_custom_poll_request_message";
|
||||
|
@ -4,8 +4,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
@ -0,0 +1,6 @@
|
||||
package org.bigbluebutton.common.messages.payload;
|
||||
|
||||
public class PubSubPingMessagePayload {
|
||||
public String system;
|
||||
public Long timestamp;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package org.bigbluebutton.common.messages;
|
||||
package org.bigbluebutton.common.messages.payload;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -2,6 +2,7 @@ package org.bigbluebutton.common.messages;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.bigbluebutton.common.messages.payload.StartCustomPollRequestMessagePayload;
|
||||
import org.junit.*;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
@ -18,15 +18,10 @@ task resolveDeps(type: Copy) {
|
||||
}
|
||||
|
||||
repositories {
|
||||
ivy {
|
||||
// URL can refer to a local directory
|
||||
//url "${System.properties['user.home']}/.ivy2/local"
|
||||
url "/home/ubuntu/.ivy2/local"
|
||||
layout "pattern", {
|
||||
artifact "[organisation]/[module]/[revision]/[artifact].[ext]"
|
||||
m2compatible = true
|
||||
ivy {
|
||||
// URL can refer to a local directory
|
||||
url "./lib"
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
add(new org.apache.ivy.plugins.resolver.ChainResolver()) {
|
||||
@ -57,7 +52,6 @@ repositories {
|
||||
mavenRepo name: "jboss", urls: "http://repository.jboss.org/nexus/content/groups/public-jboss"
|
||||
mavenRepo name: "sonatype-snapshot", urls: "http://oss.sonatype.org/content/repositories/snapshots"
|
||||
mavenRepo name: "sonatype-releases", urls: "http://oss.sonatype.org/content/repositories/releases"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,7 +82,6 @@ dependencies {
|
||||
providedCompile 'org.slf4j:jul-to-slf4j:1.7.9@jar'
|
||||
providedCompile 'org.slf4j:slf4j-api:1.7.9@jar'
|
||||
|
||||
compile "redis.clients:jedis:2.1.0"
|
||||
compile "org.codehaus.jackson:jackson-core-asl:$jacksonVersion"
|
||||
compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonVersion"
|
||||
compile "javax.servlet:com.springsource.javax.servlet.jsp.jstl:1.2.0"
|
||||
@ -106,13 +99,13 @@ dependencies {
|
||||
compile 'org.easymock:easymock:2.4@jar'
|
||||
|
||||
//redis
|
||||
//compile 'redis.clients:jedis:2.0.0'
|
||||
providedCompile 'commons-pool:commons-pool:1.5.6'
|
||||
compile "redis.clients:jedis:2.7.2"
|
||||
compile 'org.apache.commons:commons-pool2:2.3'
|
||||
|
||||
compile 'com.google.code.gson:gson:1.7.1'
|
||||
providedCompile 'org.apache.commons:commons-lang3:3.2'
|
||||
|
||||
compile 'org.bigbluebutton:bbb-common-message:0.0.12'
|
||||
compile 'org.bigbluebutton:bbb-common-message:0.0.13'
|
||||
}
|
||||
|
||||
test {
|
||||
|
@ -72,8 +72,6 @@ public class ChatClientMessageSender {
|
||||
messageInfo.put(ChatKeyUtil.FROM_COLOR, msg.messageInfo.get(ChatKeyUtil.FROM_COLOR));
|
||||
messageInfo.put(ChatKeyUtil.MESSAGE, msg.messageInfo.get(ChatKeyUtil.MESSAGE));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processSendPublicChatMessage \n" +messageInfo.toString()+ "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "ChatReceivePublicMessageCommand", messageInfo);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -90,8 +88,6 @@ public class ChatClientMessageSender {
|
||||
messageInfo.put(ChatKeyUtil.FROM_COLOR, msg.messageInfo.get(ChatKeyUtil.FROM_COLOR));
|
||||
messageInfo.put(ChatKeyUtil.MESSAGE, msg.messageInfo.get(ChatKeyUtil.MESSAGE));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processSendPrivateChatMessage \n" +messageInfo.toString()+ "\n");
|
||||
|
||||
String toUserId = msg.messageInfo.get(ChatKeyUtil.TO_USERID);
|
||||
DirectClientMessage receiver = new DirectClientMessage(msg.meetingId, toUserId, "ChatReceivePrivateMessageCommand", messageInfo);
|
||||
service.sendMessage(receiver);
|
||||
@ -102,8 +98,6 @@ public class ChatClientMessageSender {
|
||||
|
||||
private void processGetChatHistoryReply(GetChatHistoryReplyMessage gch) {
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processGetChatHistory \n" +gch.toString()+ "\n");
|
||||
|
||||
Map<String, Object> args = new HashMap<String, Object>();
|
||||
args.put("meetingId", gch.meetingId);
|
||||
args.put("requester_id", gch.requesterId);
|
||||
@ -113,10 +107,6 @@ public class ChatClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args.get("chat_history")));
|
||||
|
||||
System.out.println("*************************************************************************************\n");
|
||||
System.out.println("RedisPubSubMessageHandler - processGetChatHistoryReply \n" + gson.toJson(args) + "\n");
|
||||
System.out.println("*************************************************************************************\n");
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(gch.meetingId, gch.requesterId, "ChatRequestMessageHistoryReply", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
|
@ -101,8 +101,6 @@ public class MeetingClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processMeetingHasEndedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "meetingHasEnded", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -116,8 +114,6 @@ public class MeetingClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processMeetingStateMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "meetingState", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -138,8 +134,6 @@ public class MeetingClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processNewPermissionsSettingMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "permissionsSettingsChanged", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -152,8 +146,6 @@ public class MeetingClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processMeetingMutedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "meetingMuted", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -166,21 +158,16 @@ public class MeetingClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - handleMeetingEnded \n" + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "meetingEnded", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
|
||||
private void processDisconnectAllUsersMessage(DisconnectAllUsersMessage msg) {
|
||||
System.out.println("RedisPubSubMessageHandler - processDisconnectAllUsersMessage mid=[" + msg.meetingId + "]");
|
||||
DisconnectAllClientsMessage dm = new DisconnectAllClientsMessage(msg.meetingId);
|
||||
service.sendMessage(dm);
|
||||
}
|
||||
|
||||
private void processDisconnectUserMessage(DisconnectUserMessage msg) {
|
||||
System.out.println("RedisPubSubMessageHandler - handleDisconnectUser mid=[" + msg.meetingId + "], uid=[" + msg.userId + "]\n");
|
||||
|
||||
private void processDisconnectUserMessage(DisconnectUserMessage msg) {
|
||||
DisconnectClientMessage m = new DisconnectClientMessage(msg.meetingId, msg.userId);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -194,9 +181,7 @@ public class MeetingClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserLockedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userLocked", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
|
@ -87,9 +87,7 @@ public class PresentationClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processPresentationRemovedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "removePresentationCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -106,9 +104,7 @@ public class PresentationClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processGetPresentationInfoReplyMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requesterId, "getPresentationInfoReply", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -132,9 +128,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
// System.out.println("RedisPubSubMessageHandler - processPresentationSharedMessage \n"
|
||||
// + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "sharePresentationCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -162,9 +155,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
// System.out.println("RedisPubSubMessageHandler - processPresentationPageResized \n"
|
||||
// + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "moveCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -190,9 +180,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
// System.out.println("RedisPubSubMessageHandler - processPresentationConversionDone \n"
|
||||
// + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "conversionCompletedUpdateMessageCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -212,9 +199,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
// System.out.println("RedisPubSubMessageHandler - processGetSlideInfoReply \n"
|
||||
// + message.get("msg") + "\n");
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requesterId, "getSlideInfoReply", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -236,9 +220,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
// System.out.println("RedisPubSubMessageHandler - processPresentationConversionProgress \n"
|
||||
// + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "PresentationCursorUpdateCommand", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -260,9 +241,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
// System.out.println("RedisPubSubMessageHandler - processPresentationConversionProgress \n"
|
||||
// + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "generatedSlideUpdateMessageCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -282,9 +260,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
// System.out.println("RedisPubSubMessageHandler - processPresentationConversionProgress \n"
|
||||
// + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "conversionUpdateMessageCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -311,9 +286,6 @@ public class PresentationClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processGoToSlideMessage \n"
|
||||
+ message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "goToSlideCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ public class UserClientMessageSender {
|
||||
Iterator<String> usersIter = msg.users.iterator();
|
||||
while (usersIter.hasNext()){
|
||||
String user = usersIter.next();
|
||||
System.out.println("RedisPubSubMessageHandler - processLockLayoutMessage \n" + message + "\n");
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, user, "layoutLocked", args);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -206,7 +206,7 @@ public class UserClientMessageSender {
|
||||
Iterator<String> usersIter = msg.users.iterator();
|
||||
while (usersIter.hasNext()){
|
||||
String user = usersIter.next();
|
||||
log.debug("RedisPubSubMessageHandler - processBroadcastLayoutMessage \n" + message + "\n");
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, user, "syncLayout", args);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -221,7 +221,6 @@ public class UserClientMessageSender {
|
||||
args.put("setById", msg.setByUserid);
|
||||
args.put("layout", msg.layout);
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processGetCurrentLayoutReplyMessage \n" + message + "\n");
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requestedByUserid, "getCurrentLayoutResponse", args);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -236,7 +235,6 @@ public class UserClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
log.debug("RedisPubSubMessageHandler - handleValidateAuthTokenReply \n" + message.get("msg") + "\n");
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "validateAuthTokenReply", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -250,7 +248,6 @@ public class UserClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
log.debug("RedisPubSubMessageHandler - processValidateAuthTokenTimeoutMessage \n" + message.get("msg") + "\n");
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "validateAuthTokenTimedOut", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -263,8 +260,6 @@ public class UserClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - handleUserLeft \n" + message.get("msg") + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantLeft", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -276,16 +271,12 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - joinMeetingReply \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
String userId = msg.user.get("userId").toString();
|
||||
|
||||
DirectClientMessage jmr = new DirectClientMessage(msg.meetingId, userId, "joinMeetingReply", message);
|
||||
service.sendMessage(jmr);
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - handleUserJoined \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantJoined", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -299,9 +290,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processPresenterAssignedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "assignPresenterCallback", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -313,9 +302,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserRaisedHandMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userRaisedHand", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -328,9 +315,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserListeningOnlyMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "user_listening_only", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -343,9 +328,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserLoweredHandMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userLoweredHand", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -359,9 +342,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserStatusChangedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "participantStatusChange", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -374,9 +355,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
log.debug("RedisPubSubMessageHandler - processUserSharedWebcamMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userSharedWebcam", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -392,9 +371,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
log.debug("RedisPubSubMessageHandler - processUserUnharedWebcamMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userUnsharedWebcam", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -407,9 +384,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserJoinedVoiceMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userJoinedVoice", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -422,9 +397,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserLeftVoiceMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "userLeftVoice", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -442,9 +415,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserVoiceMutedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "voiceUserMuted", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -462,9 +433,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUserVoiceTalkingMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "voiceUserTalking", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -477,9 +446,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processRecordingStatusChangedMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "recordingStatusChanged", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -492,9 +459,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processGetRecordingStatusReplyMessage \n" + message.get("msg") + "\n");
|
||||
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.userId, "getRecordingStatusReply", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -507,11 +472,7 @@ public class UserClientMessageSender {
|
||||
Map<String, Object> message = new HashMap<String, Object>();
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("*************************************************************************************\n");
|
||||
System.out.println("RedisPubSubMessageHandler - processGetUsersReplyMessage \n" + message.get("msg") + "\n");
|
||||
System.out.println("*************************************************************************************\n");
|
||||
|
||||
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requesterId, "getUsersReply", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
|
@ -105,10 +105,6 @@ public class WhiteboardClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processGetWhiteboardShapesReplyMessage \n"
|
||||
+ message.get("msg").toString() + "\n");
|
||||
|
||||
//directed message
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requesterId, "WhiteboardRequestAnnotationHistoryReply", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -121,9 +117,6 @@ public class WhiteboardClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processClearWhiteboardReply \n" + message.toString() + "\n");
|
||||
|
||||
//directed message
|
||||
DirectClientMessage m = new DirectClientMessage(msg.meetingId, msg.requesterId, "WhiteboardIsWhiteboardEnabledReply", message);
|
||||
service.sendMessage(m);
|
||||
|
||||
@ -140,8 +133,6 @@ public class WhiteboardClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processClearWhiteboardReply \n" + message.toString() + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "WhiteboardClearCommand", message);
|
||||
service.sendMessage(m);
|
||||
}
|
||||
@ -155,8 +146,6 @@ public class WhiteboardClientMessageSender {
|
||||
Gson gson = new Gson();
|
||||
message.put("msg", gson.toJson(args));
|
||||
|
||||
System.out.println("RedisPubSubMessageHandler - processUndoWhiteboardReply \n" + message.toString() + "\n");
|
||||
|
||||
BroadcastClientMessage m = new BroadcastClientMessage(msg.meetingId, "WhiteboardUndoCommand", message);
|
||||
service.sendMessage(m);
|
||||
|
||||
|
@ -157,7 +157,6 @@ public class ConnectionInvokerService {
|
||||
if (meetingScope.hasChildScope(ScopeType.SHARED_OBJECT, msg.getSharedObjectName())) {
|
||||
ISharedObject so = getSharedObject(meetingScope, msg.getSharedObjectName());
|
||||
if (so != null) {
|
||||
System.out.println("*********** Sending [" + msg.getMessageName() + "] using shared object.");
|
||||
so.sendMessage(msg.getMessageName(), msg.getMessage());
|
||||
} else {
|
||||
System.out.println("**** Cannot get SO for [" + msg.getSharedObjectName() + "]");
|
||||
@ -180,8 +179,6 @@ public class ConnectionInvokerService {
|
||||
IConnection conn = getConnection(meetingScope, sessionId);
|
||||
if (conn != null) {
|
||||
if (conn.isConnected()) {
|
||||
log.debug("Sending message=[" + msg.getMessageName() + "] to [" + sessionId
|
||||
+ "] session on meeting=[" + msg.getMeetingID() + "]");
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
params.add(msg.getMessageName());
|
||||
params.add(msg.getMessage());
|
||||
|
@ -7,11 +7,18 @@ import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bigbluebutton.common.messages.MessageHeader;
|
||||
import org.bigbluebutton.common.messages.MessagingConstants;
|
||||
import org.bigbluebutton.common.messages.PubSubPingMessage;
|
||||
import org.bigbluebutton.common.messages.payload.PubSubPingMessagePayload;
|
||||
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
|
||||
import org.bigbluebutton.red5.client.messaging.DisconnectAllMessage;
|
||||
import org.bigbluebutton.red5.pubsub.redis.MessageSender;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class BbbAppsIsAliveMonitorService {
|
||||
private static Logger log = LoggerFactory.getLogger(BbbAppsIsAliveMonitorService.class);
|
||||
|
||||
@ -27,6 +34,14 @@ public class BbbAppsIsAliveMonitorService {
|
||||
private ConnectionInvokerService service;
|
||||
private Long lastKeepAliveMessage = 0L;
|
||||
|
||||
private MessageSender sender;
|
||||
|
||||
private final String SYSTEM_NAME = "BbbAppsRed5";
|
||||
|
||||
public void setMessageSender(MessageSender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public void setConnectionInvokerService(ConnectionInvokerService s) {
|
||||
this.service = s;
|
||||
}
|
||||
@ -41,8 +56,10 @@ public class BbbAppsIsAliveMonitorService {
|
||||
scheduledThreadPool.shutdownNow();
|
||||
}
|
||||
|
||||
public void handleKeepAliveMessage(Long startedOn, Long timestamp) {
|
||||
queueMessage(new KeepAliveMessage(startedOn, timestamp));
|
||||
public void handleKeepAliveMessage(String system, Long timestamp) {
|
||||
if (system.equals(SYSTEM_NAME)) {
|
||||
queueMessage(new KeepAliveMessage(system, timestamp));
|
||||
}
|
||||
}
|
||||
|
||||
private void queueMessage(IKeepAliveMessage msg) {
|
||||
@ -85,12 +102,14 @@ public class BbbAppsIsAliveMonitorService {
|
||||
}
|
||||
|
||||
private void processKeepAliveMessage(KeepAliveMessage msg) {
|
||||
lastKeepAliveMessage = msg.timestamp;
|
||||
lastKeepAliveMessage = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void processCheckIsAliveTimer(CheckIsAliveTimer msg) {
|
||||
if (lastKeepAliveMessage != 0 && (System.currentTimeMillis() - lastKeepAliveMessage > 10000)) {
|
||||
log.warn("BBB Apps is down. Disconnecting all clients.");
|
||||
Long now = System.currentTimeMillis();
|
||||
|
||||
if (lastKeepAliveMessage != 0 && (now - lastKeepAliveMessage > 10000)) {
|
||||
log.error("BBB Apps Red5 pubsub error!");
|
||||
service.sendMessage(new DisconnectAllMessage());
|
||||
}
|
||||
}
|
||||
@ -99,6 +118,20 @@ public class BbbAppsIsAliveMonitorService {
|
||||
public void run() {
|
||||
CheckIsAliveTimer ping = new CheckIsAliveTimer();
|
||||
queueMessage(ping);
|
||||
|
||||
PubSubPingMessage msg = new PubSubPingMessage();
|
||||
MessageHeader header = new MessageHeader();
|
||||
header.name = PubSubPingMessage.PUBSUB_PING;
|
||||
header.timestamp = System.nanoTime();
|
||||
header.replyTo = "BbbRed5";
|
||||
header.version = "0.0.1";
|
||||
PubSubPingMessagePayload payload = new PubSubPingMessagePayload();
|
||||
payload.system = SYSTEM_NAME;
|
||||
payload.timestamp = System.currentTimeMillis();
|
||||
msg.header = header;
|
||||
msg.payload = payload;
|
||||
Gson gson = new Gson();
|
||||
sender.send(MessagingConstants.TO_SYSTEM_CHANNEL, gson.toJson(msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package org.bigbluebutton.red5.monitoring;
|
||||
|
||||
import org.bigbluebutton.common.messages.BbbAppsIsAliveMessage;
|
||||
import org.bigbluebutton.common.converters.FromJsonDecoder;
|
||||
import org.bigbluebutton.common.messages.IBigBlueButtonMessage;
|
||||
import org.bigbluebutton.common.messages.PubSubPongMessage;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
@ -8,11 +11,14 @@ public class BbbAppsIsKeepAliveHandler {
|
||||
|
||||
private BbbAppsIsAliveMonitorService monitorService;
|
||||
|
||||
private final FromJsonDecoder decoder = new FromJsonDecoder();
|
||||
|
||||
public void setBbbAppsIsAliveMonitorService(BbbAppsIsAliveMonitorService s) {
|
||||
monitorService = s;
|
||||
}
|
||||
|
||||
public void handleKeepAliveMessage(String message) {
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject obj = (JsonObject) parser.parse(message);
|
||||
|
||||
@ -22,7 +28,8 @@ public class BbbAppsIsKeepAliveHandler {
|
||||
if (header.has("name")) {
|
||||
String messageName = header.get("name").getAsString();
|
||||
switch (messageName) {
|
||||
case BbbAppsIsAliveMessage.BBB_APPS_IS_ALIVE:
|
||||
case PubSubPongMessage.PUBSUB_PONG:
|
||||
|
||||
processBbbAppsIsAliveMessage(message);
|
||||
break;
|
||||
}
|
||||
@ -31,10 +38,13 @@ public class BbbAppsIsKeepAliveHandler {
|
||||
}
|
||||
|
||||
private void processBbbAppsIsAliveMessage(String json) {
|
||||
BbbAppsIsAliveMessage msg = BbbAppsIsAliveMessage.fromJson(json);
|
||||
|
||||
IBigBlueButtonMessage msg = decoder.decodeMessage(json);
|
||||
|
||||
if (msg != null) {
|
||||
monitorService.handleKeepAliveMessage(msg.startedOn, msg.timestamp);
|
||||
}
|
||||
PubSubPongMessage m = (PubSubPongMessage) msg;
|
||||
monitorService.handleKeepAliveMessage(m.payload.system, m.payload.timestamp);
|
||||
} else {
|
||||
System.out.println("***** 1 Failed to decode pong message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package org.bigbluebutton.red5.monitoring;
|
||||
|
||||
public class KeepAliveMessage implements IKeepAliveMessage {
|
||||
|
||||
public final Long startedOn;
|
||||
public final String system;
|
||||
public final Long timestamp;
|
||||
|
||||
public KeepAliveMessage(Long startedOn, Long timestamp) {
|
||||
this.startedOn = startedOn;
|
||||
public KeepAliveMessage(String system, Long timestamp) {
|
||||
this.system = system;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
@ -1,142 +0,0 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.bigbluebutton.red5.pubsub.redis;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
|
||||
public class GenericObjectPoolConfigWrapper {
|
||||
|
||||
private final GenericObjectPool.Config config;
|
||||
|
||||
public GenericObjectPoolConfigWrapper() {
|
||||
this.config = new GenericObjectPool.Config();
|
||||
}
|
||||
|
||||
public GenericObjectPool.Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public int getMaxIdle() {
|
||||
return this.config.maxIdle;
|
||||
}
|
||||
|
||||
public void setMaxIdle(int maxIdle) {
|
||||
this.config.maxIdle = maxIdle;
|
||||
}
|
||||
|
||||
public int getMinIdle() {
|
||||
return this.config.minIdle;
|
||||
}
|
||||
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.config.minIdle = minIdle;
|
||||
}
|
||||
|
||||
public int getMaxActive() {
|
||||
return this.config.maxActive;
|
||||
}
|
||||
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.config.maxActive = maxActive;
|
||||
}
|
||||
|
||||
public long getMaxWait() {
|
||||
return this.config.maxWait;
|
||||
}
|
||||
|
||||
public void setMaxWait(long maxWait) {
|
||||
this.config.maxWait = maxWait;
|
||||
}
|
||||
|
||||
public byte getWhenExhaustedAction() {
|
||||
return this.config.whenExhaustedAction;
|
||||
}
|
||||
|
||||
public void setWhenExhaustedAction(byte whenExhaustedAction) {
|
||||
this.config.whenExhaustedAction = whenExhaustedAction;
|
||||
}
|
||||
|
||||
public boolean isTestOnBorrow() {
|
||||
return this.config.testOnBorrow;
|
||||
}
|
||||
|
||||
public void setTestOnBorrow(boolean testOnBorrow) {
|
||||
this.config.testOnBorrow = testOnBorrow;
|
||||
}
|
||||
|
||||
public boolean isTestOnReturn() {
|
||||
return this.config.testOnReturn;
|
||||
}
|
||||
|
||||
public void setTestOnReturn(boolean testOnReturn) {
|
||||
this.config.testOnReturn = testOnReturn;
|
||||
}
|
||||
|
||||
public boolean isTestWhileIdle() {
|
||||
return this.config.testWhileIdle;
|
||||
}
|
||||
|
||||
public void setTestWhileIdle(boolean testWhileIdle) {
|
||||
this.config.testWhileIdle = testWhileIdle;
|
||||
}
|
||||
|
||||
public long getTimeBetweenEvictionRunsMillis() {
|
||||
return this.config.timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public void setTimeBetweenEvictionRunsMillis(
|
||||
long timeBetweenEvictionRunsMillis) {
|
||||
this.config.timeBetweenEvictionRunsMillis =
|
||||
timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public int getNumTestsPerEvictionRun() {
|
||||
return this.config.numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
|
||||
this.config.numTestsPerEvictionRun = numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
public long getMinEvictableIdleTimeMillis() {
|
||||
return this.config.minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
|
||||
this.config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public long getSoftMinEvictableIdleTimeMillis() {
|
||||
return this.config.softMinEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setSoftMinEvictableIdleTimeMillis(
|
||||
long softMinEvictableIdleTimeMillis) {
|
||||
this.config.softMinEvictableIdleTimeMillis =
|
||||
softMinEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public boolean isLifo() {
|
||||
return this.config.lifo;
|
||||
}
|
||||
|
||||
public void setLifo(boolean lifo) {
|
||||
this.config.lifo = lifo;
|
||||
}
|
||||
}
|
@ -2,13 +2,10 @@ package org.bigbluebutton.red5.pubsub.redis;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.bigbluebutton.common.messages.MessagingConstants;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
|
||||
public class MessageReceiver {
|
||||
@ -16,11 +13,14 @@ public class MessageReceiver {
|
||||
|
||||
private ReceivedMessageHandler handler;
|
||||
|
||||
private JedisPool redisPool;
|
||||
private Jedis jedis;
|
||||
private volatile boolean receiveMessage = false;
|
||||
|
||||
private final Executor msgReceiverExec = Executors.newSingleThreadExecutor();
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
public void stop() {
|
||||
receiveMessage = false;
|
||||
}
|
||||
@ -29,7 +29,10 @@ public class MessageReceiver {
|
||||
log.info("Ready to receive messages from Redis pubsub.");
|
||||
try {
|
||||
receiveMessage = true;
|
||||
final Jedis jedis = redisPool.getResource();
|
||||
jedis = new Jedis(host, port);
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
jedis.clientSetname("BbbRed5AppsSub");
|
||||
|
||||
Runnable messageReceiver = new Runnable() {
|
||||
public void run() {
|
||||
@ -45,8 +48,12 @@ public class MessageReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool){
|
||||
this.redisPool = redisPool;
|
||||
public void setHost(String host){
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setMessageHandler(ReceivedMessageHandler handler) {
|
||||
|
@ -4,26 +4,37 @@ import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.red5.logging.Red5LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
public class MessageSender {
|
||||
private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton");
|
||||
|
||||
private JedisPool redisPool;
|
||||
private volatile boolean sendMessage = false;
|
||||
|
||||
private volatile boolean sendMessage = false;
|
||||
private final Executor msgSenderExec = Executors.newSingleThreadExecutor();
|
||||
private final Executor runExec = Executors.newSingleThreadExecutor();
|
||||
private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>();
|
||||
|
||||
private JedisPool redisPool;
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
public void stop() {
|
||||
sendMessage = false;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
public void start() {
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
redisPool = new JedisPool(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null,
|
||||
Protocol.DEFAULT_DATABASE, "BbbRed5AppsPub");
|
||||
|
||||
log.info("Redis message publisher starting!");
|
||||
try {
|
||||
sendMessage = true;
|
||||
@ -60,7 +71,7 @@ public class MessageSender {
|
||||
} catch(Exception e){
|
||||
log.warn("Cannot publish the message to redis", e);
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -68,7 +79,11 @@ public class MessageSender {
|
||||
runExec.execute(task);
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool){
|
||||
this.redisPool = redisPool;
|
||||
public void setHost(String host){
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public class RedisPubSubMessageHandler implements MessageHandler {
|
||||
userMessageSender.handleUsersMessage(message);
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_WHITEBOARD_CHANNEL)) {
|
||||
whiteboardMessageSender.handleWhiteboardMessage(message);
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.BBB_APPS_KEEP_ALIVE_CHANNEL)) {
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_SYSTEM_CHANNEL)) {
|
||||
bbbAppsIsKeepAliveHandler.handleKeepAliveMessage(message);
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_DESK_SHARE_CHANNEL)) {
|
||||
deskShareMessageSender.handleDeskShareMessage(message);
|
||||
|
@ -29,13 +29,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
<bean id="red5RedisSender" class="org.bigbluebutton.red5.pubsub.redis.MessageSender"
|
||||
init-method="start" destroy-method="stop">
|
||||
<property name="redisPool"> <ref bean="redisPool"/></property>
|
||||
<property name="host" value="${redis.host}" />
|
||||
<property name="port" value="${redis.port}" />
|
||||
</bean>
|
||||
|
||||
<bean id="red5RedisReceiver" class="org.bigbluebutton.red5.pubsub.redis.MessageReceiver"
|
||||
init-method="start" destroy-method="stop">
|
||||
<property name="redisPool"> <ref bean="redisPool"/></property>
|
||||
<property name="messageHandler"> <ref local="red5RedisHandler"/> </property>
|
||||
<property name="host" value="${redis.host}" />
|
||||
<property name="port" value="${redis.port}" />
|
||||
</bean>
|
||||
|
||||
<bean id="red5RedisHandler" class="org.bigbluebutton.red5.pubsub.redis.ReceivedMessageHandler"
|
||||
|
@ -28,39 +28,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
">
|
||||
|
||||
<bean id="redisPool" class="redis.clients.jedis.JedisPool">
|
||||
<constructor-arg index="0">
|
||||
<bean factory-bean="config" factory-method="getConfig" />
|
||||
</constructor-arg>
|
||||
<constructor-arg index="1" value="${redis.host}"/>
|
||||
<constructor-arg index="2" value="${redis.port}"/>
|
||||
<constructor-arg index="0" value="${redis.host}"/>
|
||||
<constructor-arg index="1" value="${redis.port}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="config" class="org.bigbluebutton.red5.pubsub.redis.GenericObjectPoolConfigWrapper">
|
||||
<!-- Action to take when trying to acquire a connection and all connections are taken -->
|
||||
<property name="whenExhaustedAction">
|
||||
<!-- Fail-fast behaviour, we don't like to keep the kids waiting -->
|
||||
<util:constant static-field="org.apache.commons.pool.impl.GenericObjectPool.WHEN_EXHAUSTED_FAIL" />
|
||||
<!-- Default behaviour, block the caller until a resource becomes available -->
|
||||
<!--<util:constant static-field="org.apache.commons.pool.impl.GenericObjectPool.WHEN_EXHAUSTED_BLOCK" />-->
|
||||
</property>
|
||||
<!-- Maximum active connections to Redis instance -->
|
||||
<property name="maxActive" value="12" />
|
||||
<!-- Number of connections to Redis that just sit there and do nothing -->
|
||||
<property name="maxIdle" value="6" />
|
||||
<!-- Minimum number of idle connections to Redis - these can be seen as always open and ready to serve -->
|
||||
<property name="minIdle" value="1" />
|
||||
<!-- Tests whether connection is dead when connection retrieval method is called -->
|
||||
<property name="testOnBorrow" value="true" />
|
||||
<!-- Tests whether connection is dead when returning a connection to the pool -->
|
||||
<property name="testOnReturn" value="true" />
|
||||
<!-- Tests whether connections are dead during idle periods -->
|
||||
<property name="testWhileIdle" value="true" />
|
||||
<!-- Maximum number of connections to test in each idle check -->
|
||||
<property name="numTestsPerEvictionRun" value="12" />
|
||||
<!-- Idle connection checking period -->
|
||||
<property name="timeBetweenEvictionRunsMillis" value="60000" />
|
||||
<!-- Maximum time, in milliseconds, to wait for a resource when exausted action is set to WHEN_EXAUSTED_BLOCK -->
|
||||
<property name="maxWait" value="5000" />
|
||||
</bean>
|
||||
|
||||
|
||||
</beans>
|
||||
|
@ -111,6 +111,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<bean id="bbbAppsIsAliveMonitorService" class="org.bigbluebutton.red5.monitoring.BbbAppsIsAliveMonitorService"
|
||||
init-method="start" destroy-method="stop">
|
||||
<property name="connectionInvokerService"> <ref bean="connInvokerService"/></property>
|
||||
<property name="messageSender" ref="red5RedisSender"/>
|
||||
</bean>
|
||||
|
||||
<bean id="bbbAppsIsKeepAliveHandler" class="org.bigbluebutton.red5.monitoring.BbbAppsIsKeepAliveHandler">
|
||||
|
@ -877,4 +877,10 @@ Alert {
|
||||
.statusTimeStyle {
|
||||
fontSize: 10;
|
||||
paddingTop: 0;
|
||||
}
|
||||
|
||||
PollChoicesModal {
|
||||
fontSize: 14;
|
||||
paddingLeft: 16;
|
||||
paddingRight: 16;
|
||||
}
|
||||
|
@ -499,9 +499,11 @@ bbb.shortcutkey.chat.chatbox.debug = 71
|
||||
bbb.shortcutkey.chat.chatbox.debug.function = Temporary debug hotkey
|
||||
|
||||
bbb.polling.startButton.tooltip = Start a poll
|
||||
bbb.polling.startButton.label = Start Poll
|
||||
bbb.polling.publishButton.label = Publish
|
||||
bbb.polling.closeButton.label = Close
|
||||
bbb.polling.pollModal.title = Live Poll Results
|
||||
bbb.polling.customChoices.title = Enter Polling Choices
|
||||
bbb.polling.respondersLabel.novotes = Waiting for responses
|
||||
bbb.polling.respondersLabel.text = {0} Users Responded
|
||||
bbb.polling.respondersLabel.finished = Done
|
||||
|
@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
|
||||
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
|
||||
Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Lesser General Public License as published by the Free Software
|
||||
Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
BigBlueButton 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
-->
|
||||
<mx:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009"
|
||||
xmlns:s="library://ns.adobe.com/flex/spark"
|
||||
xmlns:mx="library://ns.adobe.com/flex/mx"
|
||||
width="350" layout="vertical"
|
||||
show="{focusManager.setFocus(choiceFirst)}">
|
||||
<fx:Script>
|
||||
<![CDATA[
|
||||
import com.asfusion.mate.events.Dispatcher;
|
||||
|
||||
import mx.managers.PopUpManager;
|
||||
|
||||
import org.as3commons.lang.ArrayUtils;
|
||||
import org.as3commons.lang.StringUtils;
|
||||
import org.bigbluebutton.modules.polling.events.StartCustomPollEvent;
|
||||
import org.bigbluebutton.modules.present.ui.views.PresentationWindow;
|
||||
import org.bigbluebutton.util.i18n.ResourceUtil;
|
||||
|
||||
private var _presentationWindow : PresentationWindow;
|
||||
|
||||
public function setPresentationWindow(window:PresentationWindow):void {
|
||||
_presentationWindow = window;
|
||||
}
|
||||
|
||||
protected function publishButton_clickHandler(event:MouseEvent):void {
|
||||
var answers : Array = buildAnswsers();
|
||||
if (ArrayUtils.isNotEmpty(answers)) {
|
||||
_presentationWindow.slideView.onZoomSlide(100);
|
||||
var dispatcher:Dispatcher = new Dispatcher();
|
||||
dispatchEvent(new StartCustomPollEvent("Custom", answers));
|
||||
PopUpManager.removePopUp(this);
|
||||
}
|
||||
}
|
||||
|
||||
private function buildAnswsers():Array {
|
||||
var result : Array = [];
|
||||
for each( var choice : String in [choiceFirst.text, choiceSecond.text, choiceThird.text, choiceFourth.text, choiceFifth.text, choiceSixth.text]) {
|
||||
if(!StringUtils.isBlank(StringUtils.trim(choice))) {
|
||||
result.push(StringUtils.trim(choice));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
]]>
|
||||
</fx:Script>
|
||||
|
||||
<mx:Label id="modalTitle" styleName="micSettingsWindowTitleStyle"
|
||||
text="{ResourceUtil.getInstance().getString('bbb.polling.customChoices.title')}" width="100%"/>
|
||||
|
||||
<mx:HRule width="100%"/>
|
||||
|
||||
<mx:VBox width="100%" paddingTop="20" paddingBottom="20" paddingLeft="16" paddingRight="16">
|
||||
<mx:TextInput id="choiceFirst" width="100%"/>
|
||||
<mx:TextInput id="choiceSecond" width="100%"/>
|
||||
<mx:TextInput id="choiceThird" width="100%"/>
|
||||
<mx:TextInput id="choiceFourth" width="100%"/>
|
||||
<mx:TextInput id="choiceFifth" width="100%"/>
|
||||
<mx:TextInput id="choiceSixth" width="100%"/>
|
||||
</mx:VBox>
|
||||
|
||||
<mx:HRule width="100%"/>
|
||||
|
||||
<mx:HBox width="100%" horizontalGap="10" horizontalAlign="right">
|
||||
<mx:Button id="publishButton" click="publishButton_clickHandler(event)"
|
||||
label="{ResourceUtil.getInstance().getString('bbb.polling.startButton.label')}"/>
|
||||
<mx:Button id="closeButton" click="PopUpManager.removePopUp(this)"
|
||||
label="{ResourceUtil.getInstance().getString('bbb.polling.closeButton.label')}"/>
|
||||
</mx:HBox>
|
||||
|
||||
</mx:TitleWindow>
|
@ -40,7 +40,7 @@ package org.bigbluebutton.modules.polling.views
|
||||
private const vPaddingPercent:Number = 0.25;
|
||||
private const hPaddingPercent:Number = 0.1;
|
||||
private const labelWidthPercent:Number = 0.3;
|
||||
private const labelMaxWidthInPixels:int = 40;
|
||||
private const labelMaxWidthInPixels:int = 100;
|
||||
|
||||
private var sampledata:Array = [{a:"A", v:3},
|
||||
{a:"B", v:1},
|
||||
@ -117,10 +117,11 @@ package org.bigbluebutton.modules.polling.views
|
||||
var percentText:TextField;
|
||||
var answerArray:Array = new Array();
|
||||
var percentArray:Array = new Array();
|
||||
var minFontSize:int = 20;
|
||||
var minFontSize:int = 30;
|
||||
var currFontSize:int;
|
||||
|
||||
var startingLabelWidth:Number = Math.min(labelWidthPercent*unscaledWidth, labelMaxWidthInPixels);
|
||||
//var startingLabelWidth:Number = Math.min(labelWidthPercent*unscaledWidth, labelMaxWidthInPixels);
|
||||
var startingLabelWidth:Number = labelWidthPercent*unscaledWidth;
|
||||
|
||||
graphics.lineStyle(2, colFill);
|
||||
graphics.beginFill(colFill, 1.0);
|
||||
@ -143,7 +144,7 @@ package org.bigbluebutton.modules.polling.views
|
||||
answerText.selectable = false;
|
||||
//addChild(answerText);
|
||||
answerArray.push(answerText);
|
||||
currFontSize = findFontSize(answerText, 20);
|
||||
currFontSize = findFontSize(answerText, minFontSize);
|
||||
if (currFontSize < minFontSize) minFontSize = currFontSize;
|
||||
//rowText.height = rowText.textHeight;
|
||||
answerText.x = hpadding;
|
||||
@ -158,7 +159,7 @@ package org.bigbluebutton.modules.polling.views
|
||||
percentText.selectable = false;
|
||||
//addChild(percentText);
|
||||
percentArray.push(percentText);
|
||||
currFontSize = findFontSize(percentText, 20);
|
||||
currFontSize = findFontSize(percentText, minFontSize);
|
||||
if (currFontSize < minFontSize) minFontSize = currFontSize;
|
||||
//percentText.height = percentText.textHeight;
|
||||
//percentText.x = unscaledWidth-percentStartWidth/2-percentText.width/2;
|
||||
|
@ -31,8 +31,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
verticalScrollPolicy="off"
|
||||
horizontalScrollPolicy="off"
|
||||
showControls="true" resize="resizeHandler()"
|
||||
styleNameFocus="presentationWindowStyleFocus"
|
||||
styleNameNoFocus="presentationWindowStyleNoFocus"
|
||||
styleNameFocus="presentationWindowStyleFocus"
|
||||
styleNameNoFocus="presentationWindowStyleNoFocus"
|
||||
implements="org.bigbluebutton.common.IBbbModuleWindow"
|
||||
initialize="init()"
|
||||
creationComplete="onCreationComplete()"
|
||||
@ -48,7 +48,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}" method="handleBecomePresenter" />
|
||||
<mate:Listener type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}" method="handleBecomeViewer" />
|
||||
<mate:Listener type="{PresentationChangedEvent.PRESENTATION_CHANGED_EVENT}" method="handlePresentationChangedEvent" />
|
||||
<mate:Listener type="{NavigationEvent.BIND_KEYBOARD_EVENT}" method="bindToKeyboardEvents" />
|
||||
<mate:Listener type="{NavigationEvent.BIND_KEYBOARD_EVENT}" method="bindToKeyboardEvents" />
|
||||
<mate:Listener type="{UploadEvent.CLEAR_PRESENTATION}" method="clearPresentation" />
|
||||
<mate:Listener type="{DisplaySlideEvent.DISPLAY_SLIDE_EVENT}" method="handleDisplaySlideEvent" />
|
||||
<mate:Listener type="{AddOverlayCanvasEvent.ADD_OVERLAY_CANVAS}" method="addOverlayCanvas" />
|
||||
@ -88,9 +88,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
import org.bigbluebutton.modules.polling.events.PollShowResultEvent;
|
||||
import org.bigbluebutton.modules.polling.events.PollStartedEvent;
|
||||
import org.bigbluebutton.modules.polling.events.PollStoppedEvent;
|
||||
import org.bigbluebutton.modules.polling.events.StartCustomPollEvent;
|
||||
import org.bigbluebutton.modules.polling.events.StartPollEvent;
|
||||
import org.bigbluebutton.modules.polling.events.VotePollEvent;
|
||||
import org.bigbluebutton.modules.polling.views.PollChoicesModal;
|
||||
import org.bigbluebutton.modules.polling.views.PollResultsModal;
|
||||
import org.bigbluebutton.modules.present.commands.GoToNextPageCommand;
|
||||
import org.bigbluebutton.modules.present.commands.GoToPrevPageCommand;
|
||||
@ -143,6 +143,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
private var pollMenu:Menu;
|
||||
|
||||
private var pollResultsPopUp:PollResultsModal
|
||||
private var pollChoicesPopUp:PollChoicesModal
|
||||
|
||||
[Embed(source="../../../polling/sounds/Poll.mp3")]
|
||||
private var noticeSoundClass:Class;
|
||||
@ -622,7 +623,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
constructedLabel += "/" + ResourceUtil.getInstance().getString("bbb.polling.answer."+String.fromCharCode(65+i));
|
||||
pollMenuData.push({label: constructedLabel});
|
||||
}
|
||||
pollMenuData.push({label: "Custom"});
|
||||
pollMenuData.push({label: "Custom Poll..."});
|
||||
}
|
||||
|
||||
private function onPollStartButtonClicked():void {
|
||||
@ -652,10 +653,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
private function sendStartCustomPollEvent(pollType:String):void {
|
||||
// Let's reset the page to display full size so we can display the result
|
||||
// on the bottom right-corner.
|
||||
onResetZoom();
|
||||
var dispatcher:Dispatcher = new Dispatcher();
|
||||
var answers:Array = new Array("Red", "Green", "Blue");
|
||||
dispatchEvent(new StartCustomPollEvent(pollType, answers));
|
||||
pollChoicesPopUp = PopUpManager.createPopUp(this, PollChoicesModal, true) as PollChoicesModal;
|
||||
pollChoicesPopUp.setPresentationWindow(this);
|
||||
PopUpManager.centerPopUp(pollChoicesPopUp);
|
||||
}
|
||||
|
||||
private function sendStartPollEvent(pollType:String):void {
|
||||
@ -693,10 +693,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
break;
|
||||
case 7:
|
||||
sendStartCustomPollEvent("Custom");
|
||||
//sendStartPollEvent("A-7");
|
||||
break;
|
||||
case 8:
|
||||
sendStartCustomPollEvent("Custom");
|
||||
default:
|
||||
LOGGER.warn("Wrong poll menu selected index {0}", [e.index]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -123,11 +123,12 @@ package org.bigbluebutton.modules.whiteboard.business.shapes
|
||||
var percentText:TextField;
|
||||
var answerArray:Array = new Array();
|
||||
var percentArray:Array = new Array();
|
||||
var minFontSize:int = 20;
|
||||
var minFontSize:int = 30;
|
||||
var currFontSize:int;
|
||||
|
||||
var startingLabelWidth:Number = Math.min(labelWidthPercent*graphWidth, labelMaxWidthInPixels);
|
||||
|
||||
//var startingLabelWidth:Number = Math.min(labelWidthPercent*graphWidth, labelMaxWidthInPixels);
|
||||
var startingLabelWidth:Number = labelWidthPercent*graphWidth;
|
||||
|
||||
graphics.lineStyle(2, colFill);
|
||||
graphics.beginFill(colFill, 1.0);
|
||||
for (var j:int=0, vp:int=extraVPixels, ry:int=graphY, curRowHeight:int=0; j<_data.length; j++) {
|
||||
@ -149,7 +150,7 @@ package org.bigbluebutton.modules.whiteboard.business.shapes
|
||||
answerText.selectable = false;
|
||||
//addChild(answerText);
|
||||
answerArray.push(answerText);
|
||||
currFontSize = findFontSize(answerText, 20);
|
||||
currFontSize = findFontSize(answerText, minFontSize);
|
||||
if (currFontSize < minFontSize) minFontSize = currFontSize;
|
||||
//rowText.height = rowText.textHeight;
|
||||
answerText.x = graphX + hpadding;
|
||||
@ -164,7 +165,7 @@ package org.bigbluebutton.modules.whiteboard.business.shapes
|
||||
percentText.selectable = false;
|
||||
//addChild(percentText);
|
||||
percentArray.push(percentText);
|
||||
currFontSize = findFontSize(percentText, 20);
|
||||
currFontSize = findFontSize(percentText, minFontSize);
|
||||
if (currFontSize < minFontSize) minFontSize = currFontSize;
|
||||
//percentText.height = percentText.textHeight;
|
||||
//percentText.x = graphWidth-percentStartWidth/2-percentText.width/2;
|
||||
|
@ -332,7 +332,7 @@ start_bigbluebutton () {
|
||||
#
|
||||
echo -n "Waiting for BigBlueButton to finish starting up (this may take a minute): "
|
||||
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}')
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1)
|
||||
check_no_value server_name /etc/nginx/sites-available/bigbluebutton $NGINX_IP
|
||||
|
||||
if ! nc -z -w 1 127.0.0.1 9123; then
|
||||
@ -730,7 +730,7 @@ check_configuration() {
|
||||
#
|
||||
# Check if the IP resolves to a different host
|
||||
#
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}')
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1)
|
||||
check_no_value server_name /etc/nginx/sites-available/bigbluebutton $NGINX_IP
|
||||
|
||||
HOSTS=$(which host)
|
||||
@ -772,7 +772,7 @@ check_configuration() {
|
||||
fi
|
||||
|
||||
BBB_SALT=$(cat ${SERVLET_DIR}/bigbluebutton/WEB-INF/classes/bigbluebutton.properties | tr -d '\r' | sed -n '/securitySalt/{s/.*=//;p}')
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}')
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1)
|
||||
|
||||
if [ -f /usr/local/bigbluebutton/bbb-webhooks/config_local.coffee ]; then
|
||||
WEBHOOKS_SALT=$(cat /usr/local/bigbluebutton/bbb-webhooks/config_local.coffee | grep '^[ \t]*config.bbb.sharedSecret[ =]*' | cut -d '"' -f2)
|
||||
@ -1230,6 +1230,17 @@ check_state() {
|
||||
fi
|
||||
fi
|
||||
|
||||
RED5_PID_PS=$(ps -u red5 | grep java | sed 's/^[ ]*//g' | cut -d" " -f1)
|
||||
RED5_PID_FILE=$(cat /var/run/red5.pid)
|
||||
|
||||
if [[ "$RED5_PID_PS" != "$RED5_PID_FILE" ]]; then
|
||||
echo "# Error: red5 process ID does not match value in PID file"
|
||||
echo "#"
|
||||
echo "# pid from top: $RED5_PID_PS"
|
||||
echo "# /var/run/red5.pid: $RED5_PID_FILE"
|
||||
echo "#"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
@ -1262,7 +1273,7 @@ if [ $CHECK ]; then
|
||||
PORT_IP=$(cat /var/www/bigbluebutton/client/conf/config.xml | sed -n '/porttest /{s/.*host="//;s/".*//;p}')
|
||||
echo " Port test (tunnel): $PORT_IP"
|
||||
|
||||
RED5_IP=$(cat /var/www/bigbluebutton/client/conf/config.xml | sed -n '/uri.*video/{s/.*rtmp[s]*(:\/\///;s/\/.*//;p}')
|
||||
RED5_IP=$(cat /var/www/bigbluebutton/client/conf/config.xml | sed -n '/uri.*video/{s/.*rtmp[s]*:\/\///;s/\/.*//;p}')
|
||||
WEBRTC_ENABLED_CLIENT=$(grep -i useWebrtcIfAvailable /var/www/bigbluebutton/client/conf/config.xml | cut -d '"' -f2)
|
||||
echo " Red5: $RED5_IP"
|
||||
echo " useWebrtcIfAvailable: $WEBRTC_ENABLED_CLIENT"
|
||||
@ -1276,7 +1287,7 @@ if [ $CHECK ]; then
|
||||
|
||||
echo
|
||||
echo "/etc/nginx/sites-available/bigbluebutton (nginx)"
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}')
|
||||
NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1 | cut -d' ' -f1)
|
||||
echo " server name: $NGINX_IP"
|
||||
|
||||
PORT=$(cat /etc/nginx/sites-available/bigbluebutton | sed -n '/listen/{s/.*listen[ ]*//;s/;//;p}')
|
||||
@ -1305,7 +1316,7 @@ if [ $CHECK ]; then
|
||||
fi
|
||||
|
||||
if [ -f /var/www/bigbluebutton/check/conf/config.xml ]; then
|
||||
CHECK_URL=$(cat /var/www/bigbluebutton/check/conf/config.xml | grep "<uri>rtmp" | head -1 | sed 's/.*rtmp[s]*(:\/\///g' | sed 's/\/.*//g' | tr -d '\015')
|
||||
CHECK_URL=$(cat /var/www/bigbluebutton/check/conf/config.xml | grep "<uri>rtmp" | head -1 | sed 's/.*rtmp[s]*:\/\///g' | sed 's/\/.*//g' | tr -d '\015')
|
||||
echo
|
||||
echo "/var/www/bigbluebutton/check/conf/config.xml (client check)"
|
||||
echo " client check: $CHECK_URL"
|
||||
@ -1621,6 +1632,13 @@ if [ $CLEAN ]; then
|
||||
echo "" > /var/log/syslog
|
||||
chown syslog:adm /var/log/syslog
|
||||
|
||||
if [ -d /var/log/bbb-fsesl-akka ]; then
|
||||
rm -f /var/log/bbb-fsesl-akka/*
|
||||
fi
|
||||
if [ -d /var/log/bbb-apps-akka ]; then
|
||||
rm -f /var/log/bbb-apps-akka/*
|
||||
fi
|
||||
|
||||
display_bigbluebutton_status
|
||||
|
||||
echo ""
|
||||
|
206
bigbluebutton-web/.classpath
Normal file → Executable file
206
bigbluebutton-web/.classpath
Normal file → Executable file
@ -1,103 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/java"/>
|
||||
<classpathentry kind="src" path="src/groovy"/>
|
||||
<classpathentry kind="src" path="grails-app/conf"/>
|
||||
<classpathentry kind="src" path="grails-app/controllers"/>
|
||||
<classpathentry kind="src" path="grails-app/domain"/>
|
||||
<classpathentry kind="src" path="grails-app/services"/>
|
||||
<classpathentry kind="src" path="grails-app/taglib"/>
|
||||
<classpathentry kind="src" path="test/integration"/>
|
||||
<classpathentry kind="src" path="test/unit"/>
|
||||
<classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
|
||||
<classpathentry kind="lib" path="lib/geronimo-j2ee-management_1.0_spec-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/ant/lib/ant.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-pool-1.2.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/xpp3_min-1.1.3.4.O.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/spring-webmvc-2.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/sitemesh-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ehcache-1.5.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-beanutils-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/servlet-api-2.5-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/slf4j-log4j12-1.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.webflow-2.0.3.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-cli-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/standard-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-codec-1.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/serializer.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-lang-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-nodeps-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-validator-1.3.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/spring-test-2.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/backport-util-concurrent-3.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/svnkit-1.2.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/slf4j-api-1.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-io-1.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/junit-3.8.2.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-launcher-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/spring-2.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jstl-2.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.js-2.0.3.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/gant_groovy1.6-1.6.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-trax.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ognl-2.6.9.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-util-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jline-0.9.91.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jasper-compiler-jdt-5.5.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/hsqldb-1.8.0.5.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/antlr-2.7.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.binding-2.0.3.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jasper-compiler-5.5.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/log4j-1.2.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-dbcp-1.2.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/oro-2.0.8.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jstl-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-collections-3.2.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jsr107cache-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jsp-api-2.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-naming-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ivy-2.0.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jasper-runtime-5.5.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/start.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ejb3-persistence-3.3.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-plus-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-el-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/cglib-nodep-2.1_3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jsp-api-2.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-fileupload-1.2.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/oscache-2.4.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/standard-2.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/groovy-all-1.6.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-junit-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jta-1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jcl-over-slf4j-1.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-gorm-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-scripts-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-webflow-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-core-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-test-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-crud-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-spring-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-bootstrap-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-resources-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-web-1.1.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jodconverter-2.2.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/juh-3.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jurt-3.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/ridl-3.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/unoil-3.0.1.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/commons-pool-1.5.6.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-lang-2.5.jar"/>
|
||||
<classpathentry kind="lib" path="lib/gson-1.7.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jedis-2.0.0.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.8.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-io-2.4.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-httpclient-3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/slf4j-api-1.7.5.jar"/>
|
||||
<classpathentry kind="output" path="web-app/WEB-INF/classes"/>
|
||||
</classpath>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/java"/>
|
||||
<classpathentry kind="src" path="src/groovy"/>
|
||||
<classpathentry kind="src" path="grails-app/conf"/>
|
||||
<classpathentry kind="src" path="grails-app/controllers"/>
|
||||
<classpathentry kind="src" path="grails-app/domain"/>
|
||||
<classpathentry kind="src" path="grails-app/services"/>
|
||||
<classpathentry kind="src" path="grails-app/taglib"/>
|
||||
<classpathentry kind="src" path="test/integration"/>
|
||||
<classpathentry kind="src" path="test/unit"/>
|
||||
<classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
|
||||
<classpathentry kind="lib" path="lib/geronimo-j2ee-management_1.0_spec-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/ant/lib/ant.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-pool-1.2.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/xpp3_min-1.1.3.4.O.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/spring-webmvc-2.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/sitemesh-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ehcache-1.5.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-beanutils-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/servlet-api-2.5-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/slf4j-log4j12-1.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.webflow-2.0.3.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-cli-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/standard-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-codec-1.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/serializer.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-lang-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-nodeps-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-validator-1.3.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/spring-test-2.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/backport-util-concurrent-3.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/svnkit-1.2.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/slf4j-api-1.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-io-1.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/junit-3.8.2.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-launcher-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/spring-2.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jstl-2.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.js-2.0.3.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/gant_groovy1.6-1.6.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-trax.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ognl-2.6.9.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-util-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jline-0.9.91.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jasper-compiler-jdt-5.5.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/hsqldb-1.8.0.5.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/antlr-2.7.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/org.springframework.binding-2.0.3.RELEASE.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jasper-compiler-5.5.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/log4j-1.2.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-dbcp-1.2.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/oro-2.0.8.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jstl-2.4.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-collections-3.2.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jsr107cache-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jsp-api-2.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-naming-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ivy-2.0.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jasper-runtime-5.5.15.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/start.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ejb3-persistence-3.3.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jetty-plus-6.1.14.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-el-1.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/cglib-nodep-2.1_3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jsp-api-2.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/commons-fileupload-1.2.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/oscache-2.4.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/standard-2.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/groovy-all-1.6.3.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/ant-junit-1.7.0.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jta-1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/lib/jcl-over-slf4j-1.5.6.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-gorm-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-scripts-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-webflow-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-core-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-test-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-crud-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-spring-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-bootstrap-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-resources-1.1.1.jar"/>
|
||||
<classpathentry kind="var" path="GRAILS_HOME/dist/grails-web-1.1.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jodconverter-2.2.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/juh-3.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jurt-3.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/ridl-3.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/unoil-3.0.1.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/commons-cli-1.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-lang-2.5.jar"/>
|
||||
<classpathentry kind="lib" path="lib/gson-1.7.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.8.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-io-2.4.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-httpclient-3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-pool2-2.3.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jedis-2.7.2.jar"/>
|
||||
<classpathentry kind="lib" path="lib/bbb-common-message-0.0.13.jar"/>
|
||||
<classpathentry kind="output" path="web-app/WEB-INF/classes"/>
|
||||
</classpath>
|
||||
|
70
bigbluebutton-web/build.gradle
Normal file → Executable file
70
bigbluebutton-web/build.gradle
Normal file → Executable file
@ -8,47 +8,51 @@ task resolveDeps(type: Copy) {
|
||||
}
|
||||
|
||||
repositories {
|
||||
add(new org.apache.ivy.plugins.resolver.ChainResolver()) {
|
||||
name = 'remote'
|
||||
returnFirst = true
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "googlecode"
|
||||
addArtifactPattern "http://red5.googlecode.com/svn/repository/[artifact](-[revision]).[ext]"
|
||||
addArtifactPattern "http://red5.googlecode.com/svn/repository/[organisation]/[artifact](-[revision]).[ext]"
|
||||
}
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "blindside-repos"
|
||||
addArtifactPattern "http://blindside.googlecode.com/svn/repository/[artifact](-[revision]).[ext]"
|
||||
addArtifactPattern "http://blindside.googlecode.com/svn/repository/[organisation]/[artifact](-[revision]).[ext]"
|
||||
}
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "maven2-central"
|
||||
m2compatible = true
|
||||
addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact](-[revision]).[ext]"
|
||||
addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[artifact]/[revision]/[artifact](-[revision]).[ext]"
|
||||
}
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "testng_ibiblio_maven2"
|
||||
m2compatible = true
|
||||
addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact](-[revision])-jdk15.[ext]"
|
||||
addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[artifact]/[revision]/[artifact](-[revision])-jdk15.[ext]"
|
||||
}
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
add(new org.apache.ivy.plugins.resolver.ChainResolver()) {
|
||||
name = 'remote'
|
||||
returnFirst = true
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "googlecode"
|
||||
addArtifactPattern "http://red5.googlecode.com/svn/repository/[artifact](-[revision]).[ext]"
|
||||
addArtifactPattern "http://red5.googlecode.com/svn/repository/[organisation]/[artifact](-[revision]).[ext]"
|
||||
}
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "blindside-repos"
|
||||
addArtifactPattern "http://blindside.googlecode.com/svn/repository/[artifact](-[revision]).[ext]"
|
||||
addArtifactPattern "http://blindside.googlecode.com/svn/repository/[organisation]/[artifact](-[revision]).[ext]"
|
||||
}
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "testng_ibiblio_maven2"
|
||||
m2compatible = true
|
||||
addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact](-[revision])-jdk15.[ext]"
|
||||
addArtifactPattern "http://repo1.maven.org/maven2/[organisation]/[artifact]/[revision]/[artifact](-[revision])-jdk15.[ext]"
|
||||
}
|
||||
add(new org.apache.ivy.plugins.resolver.URLResolver()) {
|
||||
name = "spring-bundles"
|
||||
m2compatible = true
|
||||
addArtifactPattern "http://repository.springsource.com/maven/bundles/external/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
|
||||
addArtifactPattern "http://repository.springsource.com/maven/bundles/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
|
||||
}
|
||||
mavenRepo name: "jboss", urls: "http://repository.jboss.org/nexus/content/groups/public-jboss"
|
||||
mavenRepo name: "sonatype-snapshot", urls: "http://oss.sonatype.org/content/repositories/snapshots"
|
||||
mavenRepo name: "sonatype-releases", urls: "http://oss.sonatype.org/content/repositories/releases"
|
||||
}
|
||||
ivy {
|
||||
// URL can refer to a local directory
|
||||
url "./lib"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//redis
|
||||
compile 'redis.clients:jedis:2.0.0'
|
||||
compile 'commons-pool:commons-pool:1.5.6'
|
||||
//redis
|
||||
compile "redis.clients:jedis:2.7.2"
|
||||
compile 'org.apache.commons:commons-pool2:2.3'
|
||||
|
||||
compile 'commons-lang:commons-lang:2.5'
|
||||
compile 'commons-io:commons-io:2.4'
|
||||
compile 'com.google.code.gson:gson:1.7.1'
|
||||
compile 'com.google.code.gson:gson:1.7.1'
|
||||
compile 'commons-httpclient:commons-httpclient:3.1'
|
||||
|
||||
compile 'org.bigbluebutton:bbb-common-message:0.0.13'
|
||||
|
||||
// Logging
|
||||
// Commenting out as it results in build failure (ralam - may 11, 2014)
|
||||
//compile 'ch.qos.logback:logback-core:1.0.9@jar'
|
||||
|
@ -27,18 +27,22 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
http://www.springframework.org/schema/util/spring-util-2.0.xsd
|
||||
">
|
||||
|
||||
<bean id="redisStorageService" class="org.bigbluebutton.api.messaging.RedisStorageService">
|
||||
<property name="redisPool"> <ref bean="redisPool"/></property>
|
||||
<bean id="redisStorageService" class="org.bigbluebutton.api.messaging.RedisStorageService"
|
||||
init-method="start" destroy-method="stop">
|
||||
<property name="host" value="${redisHost}" />
|
||||
<property name="port" value="${redisPort}" />
|
||||
</bean>
|
||||
|
||||
<bean id="messageSender" class="org.bigbluebutton.api.messaging.MessageSender"
|
||||
init-method="start" destroy-method="stop">
|
||||
<property name="redisPool"> <ref bean="redisPool"/></property>
|
||||
<property name="host" value="${redisHost}" />
|
||||
<property name="port" value="${redisPort}" />
|
||||
</bean>
|
||||
|
||||
<bean id="redisMessageReceiver" class="org.bigbluebutton.api.messaging.MessageReceiver"
|
||||
init-method="start" destroy-method="stop">
|
||||
<property name="redisPool"> <ref bean="redisPool"/></property>
|
||||
<property name="host" value="${redisHost}" />
|
||||
<property name="port" value="${redisPort}" />
|
||||
<property name="messageHandler"> <ref local="redisMessageHandler"/> </property>
|
||||
</bean>
|
||||
|
||||
|
@ -27,40 +27,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
http://www.springframework.org/schema/util/spring-util-2.0.xsd
|
||||
">
|
||||
|
||||
<bean id="redisPool" class="redis.clients.jedis.JedisPool">
|
||||
<constructor-arg index="0">
|
||||
<bean factory-bean="config" factory-method="getConfig" />
|
||||
</constructor-arg>
|
||||
<constructor-arg index="1" value="${redisHost}"/>
|
||||
<constructor-arg index="2" value="${redisPort}"/>
|
||||
</bean>
|
||||
|
||||
<bean id="config" class="org.bigbluebutton.api.messaging.GenericObjectPoolConfigWrapper">
|
||||
<!-- Action to take when trying to acquire a connection and all connections are taken -->
|
||||
<property name="whenExhaustedAction">
|
||||
<!-- Fail-fast behaviour, we don't like to keep the kids waiting -->
|
||||
<util:constant static-field="org.apache.commons.pool.impl.GenericObjectPool.WHEN_EXHAUSTED_FAIL" />
|
||||
<!-- Default behaviour, block the caller until a resource becomes available -->
|
||||
<!--<util:constant static-field="org.apache.commons.pool.impl.GenericObjectPool.WHEN_EXHAUSTED_BLOCK" />-->
|
||||
</property>
|
||||
<!-- Maximum active connections to Redis instance -->
|
||||
<property name="maxActive" value="12" />
|
||||
<!-- Number of connections to Redis that just sit there and do nothing -->
|
||||
<property name="maxIdle" value="6" />
|
||||
<!-- Minimum number of idle connections to Redis - these can be seen as always open and ready to serve -->
|
||||
<property name="minIdle" value="1" />
|
||||
<!-- Tests whether connection is dead when connection retrieval method is called -->
|
||||
<property name="testOnBorrow" value="true" />
|
||||
<!-- Tests whether connection is dead when returning a connection to the pool -->
|
||||
<property name="testOnReturn" value="true" />
|
||||
<!-- Tests whether connections are dead during idle periods -->
|
||||
<property name="testWhileIdle" value="true" />
|
||||
<!-- Maximum number of connections to test in each idle check -->
|
||||
<property name="numTestsPerEvictionRun" value="12" />
|
||||
<!-- Idle connection checking period -->
|
||||
<property name="timeBetweenEvictionRunsMillis" value="60000" />
|
||||
<!-- Maximum time, in milliseconds, to wait for a resource when exausted action is set to WHEN_EXAUSTED_BLOCK -->
|
||||
<property name="maxWait" value="5000" />
|
||||
</bean>
|
||||
|
||||
|
||||
</beans>
|
||||
|
@ -1,127 +0,0 @@
|
||||
/**
|
||||
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||
*
|
||||
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* BigBlueButton 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along
|
||||
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.bigbluebutton.api.messaging;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;;
|
||||
|
||||
public class GenericObjectPoolConfigWrapper {
|
||||
|
||||
private final GenericObjectPool.Config config;
|
||||
|
||||
public GenericObjectPoolConfigWrapper() {
|
||||
this.config = new GenericObjectPool.Config();
|
||||
}
|
||||
|
||||
public GenericObjectPool.Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public int getMaxIdle() {
|
||||
return this.config.maxIdle;
|
||||
}
|
||||
|
||||
public void setMaxIdle(int maxIdle) {
|
||||
this.config.maxIdle = maxIdle;
|
||||
}
|
||||
|
||||
public int getMinIdle() {
|
||||
return this.config.minIdle;
|
||||
}
|
||||
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.config.minIdle = minIdle;
|
||||
}
|
||||
|
||||
public int getMaxActive() {
|
||||
return this.config.maxActive;
|
||||
}
|
||||
|
||||
public void setMaxActive(int maxActive) {
|
||||
this.config.maxActive = maxActive;
|
||||
}
|
||||
|
||||
public long getMaxWait() {
|
||||
return this.config.maxWait;
|
||||
}
|
||||
|
||||
public void setMaxWait(long maxWait) {
|
||||
this.config.maxWait = maxWait;
|
||||
}
|
||||
|
||||
public byte getWhenExhaustedAction() {
|
||||
return this.config.whenExhaustedAction;
|
||||
}
|
||||
|
||||
public void setWhenExhaustedAction(byte whenExhaustedAction) {
|
||||
this.config.whenExhaustedAction = whenExhaustedAction;
|
||||
}
|
||||
|
||||
public boolean isTestOnBorrow() {
|
||||
return this.config.testOnBorrow;
|
||||
}
|
||||
|
||||
public void setTestOnBorrow(boolean testOnBorrow) {
|
||||
this.config.testOnBorrow = testOnBorrow;
|
||||
}
|
||||
|
||||
public boolean isTestOnReturn() {
|
||||
return this.config.testOnReturn;
|
||||
}
|
||||
|
||||
public void setTestOnReturn(boolean testOnReturn) {
|
||||
this.config.testOnReturn = testOnReturn;
|
||||
}
|
||||
|
||||
public boolean isTestWhileIdle() {
|
||||
return this.config.testWhileIdle;
|
||||
}
|
||||
|
||||
public void setTestWhileIdle(boolean testWhileIdle) {
|
||||
this.config.testWhileIdle = testWhileIdle;
|
||||
}
|
||||
|
||||
public long getTimeBetweenEvictionRunsMillis() {
|
||||
return this.config.timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public void setTimeBetweenEvictionRunsMillis(
|
||||
long timeBetweenEvictionRunsMillis) {
|
||||
this.config.timeBetweenEvictionRunsMillis =
|
||||
timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
public int getNumTestsPerEvictionRun() {
|
||||
return this.config.numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
|
||||
this.config.numTestsPerEvictionRun = numTestsPerEvictionRun;
|
||||
}
|
||||
|
||||
public long getMinEvictableIdleTimeMillis() {
|
||||
return this.config.minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
|
||||
this.config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package org.bigbluebutton.api.messaging;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.bigbluebutton.api.messaging.messages.IMessage;
|
||||
import org.bigbluebutton.api.messaging.messages.KeepAliveReply;
|
||||
import org.bigbluebutton.api.messaging.messages.MeetingDestroyed;
|
||||
import org.bigbluebutton.api.messaging.messages.MeetingEnded;
|
||||
@ -14,9 +15,13 @@ import org.bigbluebutton.api.messaging.messages.UserListeningOnly;
|
||||
import org.bigbluebutton.api.messaging.messages.UserSharedWebcam;
|
||||
import org.bigbluebutton.api.messaging.messages.UserStatusChanged;
|
||||
import org.bigbluebutton.api.messaging.messages.UserUnsharedWebcam;
|
||||
import org.bigbluebutton.common.converters.FromJsonDecoder;
|
||||
import org.bigbluebutton.common.messages.BbbAppsIsAliveMessage;
|
||||
import org.bigbluebutton.common.messages.IBigBlueButtonMessage;
|
||||
import org.bigbluebutton.common.messages.PubSubPongMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
@ -25,6 +30,7 @@ public class MeetingMessageHandler implements MessageHandler {
|
||||
private static Logger log = LoggerFactory.getLogger(MeetingMessageHandler.class);
|
||||
|
||||
private Set<MessageListener> listeners;
|
||||
private final FromJsonDecoder decoder = new FromJsonDecoder();
|
||||
|
||||
public void setMessageListeners(Set<MessageListener> listeners) {
|
||||
this.listeners = listeners;
|
||||
@ -65,7 +71,7 @@ public class MeetingMessageHandler implements MessageHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.BBB_APPS_KEEP_ALIVE_CHANNEL)) {
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_SYSTEM_CHANNEL)) {
|
||||
|
||||
if (obj.has("header") && obj.has("payload")) {
|
||||
JsonObject header = (JsonObject) obj.get("header");
|
||||
@ -73,15 +79,25 @@ public class MeetingMessageHandler implements MessageHandler {
|
||||
|
||||
if (header.has("name")) {
|
||||
String messageName = header.get("name").getAsString();
|
||||
// System.out.println("Received [" + messageName + "] message on channel [" + channel + "].");
|
||||
for (MessageListener listener : listeners) {
|
||||
if (BbbAppsIsAliveMessage.BBB_APPS_IS_ALIVE.equalsIgnoreCase(messageName)){
|
||||
BbbAppsIsAliveMessage msg = BbbAppsIsAliveMessage.fromJson(message);
|
||||
listener.handle(new KeepAliveReply(msg.startedOn, msg.timestamp));
|
||||
}
|
||||
IMessage rxMsg = null;
|
||||
if (PubSubPongMessage.PUBSUB_PONG.equals(messageName)) {
|
||||
IBigBlueButtonMessage msg = decoder.decodeMessage(message);
|
||||
if (msg != null) {
|
||||
PubSubPongMessage m = (PubSubPongMessage) msg;
|
||||
rxMsg = new KeepAliveReply(m.payload.system, m.payload.timestamp);
|
||||
} else {
|
||||
System.out.println("***** 1 Failed to decode pong message");
|
||||
}
|
||||
}
|
||||
//System.out.println("Received [" + messageName + "] message on channel [" + channel + "].");
|
||||
if (rxMsg != null) {
|
||||
for (MessageListener listener : listeners) {
|
||||
listener.handle(rxMsg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_USERS_CHANNEL)) {
|
||||
if (obj.has("header") && obj.has("payload")) {
|
||||
JsonObject header = (JsonObject) obj.get("header");
|
||||
@ -92,7 +108,7 @@ public class MeetingMessageHandler implements MessageHandler {
|
||||
System.out.println("Received [" + messageName + "] message on channel [" + channel + "].");
|
||||
|
||||
if (MessagingConstants.USER_JOINED_EVENT.equalsIgnoreCase(messageName)) {
|
||||
System.out.println("Handling [" + messageName + "] message.");
|
||||
System.out.println("Handling [" + messageName + "] message.");
|
||||
String meetingId = payload.get("meeting_id").getAsString();
|
||||
JsonObject user = (JsonObject) payload.get("user");
|
||||
|
||||
|
20
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageReceiver.java
Normal file → Executable file
20
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageReceiver.java
Normal file → Executable file
@ -2,8 +2,10 @@ package org.bigbluebutton.api.messaging;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
@ -13,12 +15,15 @@ public class MessageReceiver {
|
||||
|
||||
private ReceivedMessageHandler handler;
|
||||
|
||||
private JedisPool redisPool;
|
||||
private Jedis jedis;
|
||||
private volatile boolean receiveMessage = false;
|
||||
|
||||
private final Executor msgReceiverExec = Executors.newSingleThreadExecutor();
|
||||
private final Executor runExec = Executors.newSingleThreadExecutor();
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
public void stop() {
|
||||
receiveMessage = false;
|
||||
}
|
||||
@ -27,7 +32,10 @@ public class MessageReceiver {
|
||||
log.info("Ready to receive messages from Redis pubsub.");
|
||||
try {
|
||||
receiveMessage = true;
|
||||
final Jedis jedis = redisPool.getResource();
|
||||
jedis = new Jedis(host, port);
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
jedis.clientSetname("BbbWebSub");
|
||||
|
||||
Runnable messageReceiver = new Runnable() {
|
||||
public void run() {
|
||||
@ -42,8 +50,12 @@ public class MessageReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool){
|
||||
this.redisPool = redisPool;
|
||||
public void setHost(String host){
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void setMessageHandler(ReceivedMessageHandler handler) {
|
||||
|
20
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageSender.java
Normal file → Executable file
20
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessageSender.java
Normal file → Executable file
@ -4,10 +4,12 @@ import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
public class MessageSender {
|
||||
private static Logger log = LoggerFactory.getLogger(MessageSender.class);
|
||||
@ -19,11 +21,19 @@ public class MessageSender {
|
||||
private final Executor runExec = Executors.newSingleThreadExecutor();
|
||||
private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>();
|
||||
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
public void stop() {
|
||||
sendMessage = false;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
redisPool = new JedisPool(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null,
|
||||
Protocol.DEFAULT_DATABASE, "BbbWebPub");
|
||||
|
||||
log.info("Redis message publisher starting!");
|
||||
try {
|
||||
sendMessage = true;
|
||||
@ -60,7 +70,7 @@ public class MessageSender {
|
||||
} catch(Exception e){
|
||||
log.warn("Cannot publish the message to redis", e);
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -68,7 +78,11 @@ public class MessageSender {
|
||||
runExec.execute(task);
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool){
|
||||
this.redisPool = redisPool;
|
||||
public void setHost(String host){
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
|
2
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java
Normal file → Executable file
2
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/MessagingService.java
Normal file → Executable file
@ -36,5 +36,5 @@ public interface MessagingService {
|
||||
boolean removeSubscription(String meetingId, String subscriptionId);
|
||||
List<Map<String,String>> listSubscriptions(String meetingId);
|
||||
void registerUser(String meetingID, String internalUserId, String fullname, String role, String externUserID, String authToken);
|
||||
void sendKeepAlive(String keepAliveId);
|
||||
void sendKeepAlive(String system, Long timestamp);
|
||||
}
|
||||
|
17
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java
Normal file → Executable file
17
bigbluebutton-web/src/java/org/bigbluebutton/api/messaging/RedisMessagingService.java
Normal file → Executable file
@ -27,16 +27,25 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.bigbluebutton.api.messaging.converters.messages.CreateMeetingMessage;
|
||||
import org.bigbluebutton.api.messaging.converters.messages.DestroyMeetingMessage;
|
||||
import org.bigbluebutton.api.messaging.converters.messages.EndMeetingMessage;
|
||||
import org.bigbluebutton.api.messaging.converters.messages.KeepAliveMessage;
|
||||
import org.bigbluebutton.api.messaging.converters.messages.RegisterUserMessage;
|
||||
import org.bigbluebutton.common.converters.ToJsonEncoder;
|
||||
import org.bigbluebutton.common.messages.MessageHeader;
|
||||
import org.bigbluebutton.common.messages.MessagingConstants;
|
||||
import org.bigbluebutton.common.messages.PubSubPingMessage;
|
||||
import org.bigbluebutton.common.messages.payload.PubSubPingMessagePayload;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPubSub;
|
||||
@ -46,6 +55,7 @@ public class RedisMessagingService implements MessagingService {
|
||||
|
||||
private RedisStorageService storeService;
|
||||
private MessageSender sender;
|
||||
private ToJsonEncoder encoder = new ToJsonEncoder();
|
||||
|
||||
public void recordMeetingInfo(String meetingId, Map<String, String> info) {
|
||||
storeService.recordMeetingInfo(meetingId, info);
|
||||
@ -86,10 +96,9 @@ public class RedisMessagingService implements MessagingService {
|
||||
sender.send(MessagingConstants.TO_MEETING_CHANNEL, json);
|
||||
}
|
||||
|
||||
public void sendKeepAlive(String keepAliveId) {
|
||||
KeepAliveMessage msg = new KeepAliveMessage(keepAliveId);
|
||||
String json = MessageToJson.keepAliveMessageToJson(msg);
|
||||
sender.send(MessagingConstants.TO_SYSTEM_CHANNEL, json);
|
||||
public void sendKeepAlive(String system, Long timestamp) {
|
||||
String json = encoder.encodePubSubPingMessage("BbbWeb", System.currentTimeMillis());
|
||||
sender.send(MessagingConstants.TO_SYSTEM_CHANNEL, json);
|
||||
}
|
||||
|
||||
public void send(String channel, String message) {
|
||||
|
@ -4,16 +4,33 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.Protocol;
|
||||
|
||||
public class RedisStorageService {
|
||||
private static Logger log = LoggerFactory.getLogger(RedisStorageService.class);
|
||||
|
||||
private JedisPool redisPool;
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
|
||||
public void start() {
|
||||
// Set the name of this client to be able to distinguish when doing
|
||||
// CLIENT LIST on redis-cli
|
||||
redisPool = new JedisPool(new GenericObjectPoolConfig(), host, port, Protocol.DEFAULT_TIMEOUT, null,
|
||||
Protocol.DEFAULT_DATABASE, "BbbRed5AppsPub");
|
||||
|
||||
}
|
||||
|
||||
public void recordMeetingInfo(String meetingId, Map<String, String> info) {
|
||||
Jedis jedis = redisPool.getResource();
|
||||
try {
|
||||
@ -26,7 +43,7 @@ public class RedisStorageService {
|
||||
} catch (Exception e){
|
||||
log.warn("Cannot record the info meeting:"+meetingId,e);
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,7 +53,7 @@ public class RedisStorageService {
|
||||
jedis.del("meeting-" + meetingId);
|
||||
jedis.srem("meetings", meetingId);
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +70,7 @@ public class RedisStorageService {
|
||||
} catch (Exception e){
|
||||
log.warn("Cannot list subscriptions:" + meetingId, e);
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
|
||||
return list;
|
||||
@ -68,7 +85,7 @@ public class RedisStorageService {
|
||||
log.warn("Cannot rmove subscription:" + meetingId, e);
|
||||
unsubscribed = false;
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
|
||||
return unsubscribed;
|
||||
@ -93,13 +110,17 @@ public class RedisStorageService {
|
||||
} catch (Exception e){
|
||||
log.warn("Cannot store subscription:" + meetingId, e);
|
||||
} finally {
|
||||
redisPool.returnResource(jedis);
|
||||
jedis.close();
|
||||
}
|
||||
|
||||
return sid;
|
||||
}
|
||||
|
||||
public void setRedisPool(JedisPool redisPool){
|
||||
this.redisPool=redisPool;
|
||||
public void setHost(String host){
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package org.bigbluebutton.api.messaging.messages;
|
||||
|
||||
public class KeepAliveReply implements IMessage {
|
||||
|
||||
public final Long startedOn;
|
||||
public final String system;
|
||||
public final Long timestamp;
|
||||
|
||||
public KeepAliveReply(Long startedOn, Long timestamp) {
|
||||
this.startedOn = startedOn;
|
||||
public KeepAliveReply(String system, Long timestamp) {
|
||||
this.system = system;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ package org.bigbluebutton.web.services;
|
||||
|
||||
public class KeepAlivePong implements KeepAliveMessage {
|
||||
|
||||
public final Long startedOn;
|
||||
public final String system;
|
||||
public final Long timestamp;
|
||||
|
||||
public KeepAlivePong(Long startedOn, Long timestamp) {
|
||||
this.startedOn = startedOn;
|
||||
public KeepAlivePong(String system, Long timestamp) {
|
||||
this.system = system;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,8 @@ public class KeepAliveService implements MessageListener {
|
||||
|
||||
private Long lastKeepAliveMessage = 0L;
|
||||
|
||||
private final String SYSTEM = "BbbWeb";
|
||||
|
||||
public void start() {
|
||||
scheduledThreadPool.scheduleWithFixedDelay(task, 5000, runEvery, TimeUnit.MILLISECONDS);
|
||||
processKeepAliveMessage();
|
||||
@ -131,29 +133,33 @@ public class KeepAliveService implements MessageListener {
|
||||
}
|
||||
|
||||
private void processPing(KeepAlivePing msg) {
|
||||
service.sendKeepAlive(SYSTEM, System.currentTimeMillis());
|
||||
|
||||
if (lastKeepAliveMessage != 0 && (System.currentTimeMillis() - lastKeepAliveMessage > 10000)) {
|
||||
log.warn("BBB Apps is down. Making service unavailable.");
|
||||
log.error("BBB Web pubsub error!");
|
||||
// BBB-Apps has gone down. Mark it as unavailable. (ralam - april 29, 2014)
|
||||
available = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void processPong(KeepAlivePong msg) {
|
||||
log.debug("Received BBB Apps Is Alive.");
|
||||
lastKeepAliveMessage = msg.timestamp;
|
||||
lastKeepAliveMessage = System.currentTimeMillis();
|
||||
available = true;
|
||||
}
|
||||
|
||||
private void handleKeepAliveReply(Long startedOn, Long timestamp) {
|
||||
KeepAlivePong pong = new KeepAlivePong(startedOn, timestamp);
|
||||
queueMessage(pong);
|
||||
private void handleKeepAliveReply(String system, Long timestamp) {
|
||||
if (system.equals("BbbWeb")) {
|
||||
KeepAlivePong pong = new KeepAlivePong(system, timestamp);
|
||||
queueMessage(pong);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(IMessage message) {
|
||||
if (message instanceof KeepAliveReply) {
|
||||
KeepAliveReply msg = (KeepAliveReply) message;
|
||||
handleKeepAliveReply(msg.startedOn, msg.timestamp);
|
||||
handleKeepAliveReply(msg.system, msg.timestamp);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user