Merge branch 'master' of github.com:bigbluebutton/bigbluebutton into webrtc-desktop-share-merging

This commit is contained in:
Anton Georgiev 2015-08-24 14:31:00 +00:00
commit eb57aa7da1
64 changed files with 788 additions and 933 deletions

View File

@ -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

View File

@ -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 + "]");
}
}
}
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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)
}
}
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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")
}

View File

@ -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)
}

View File

@ -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"
)}

View File

@ -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);

View File

@ -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")
}

View File

@ -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) {

View File

@ -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 + "]")

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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";

View File

@ -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;

View File

@ -0,0 +1,6 @@
package org.bigbluebutton.common.messages.payload;
public class PubSubPingMessagePayload {
public String system;
public Long timestamp;
}

View File

@ -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;

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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());

View File

@ -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));
}
}
}

View File

@ -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");
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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"

View File

@ -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>

View File

@ -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">

View File

@ -877,4 +877,10 @@ Alert {
.statusTimeStyle {
fontSize: 10;
paddingTop: 0;
}
PollChoicesModal {
fontSize: 14;
paddingLeft: 16;
paddingRight: 16;
}

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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
View 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
View 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'

View File

@ -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>

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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");

View 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) {

View 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;
}
}

View 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);
}

View 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) {

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}