Merge pull request #665 from ritzalam/implement-polling-v3

Implement polling v3
This commit is contained in:
Richard Alam 2015-06-22 17:30:24 -04:00
commit 84446f93fa
22 changed files with 665 additions and 80 deletions

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.4"
"org.bigbluebutton" % "bbb-common-message" % "0.0.5"
)}

View File

@ -17,6 +17,11 @@ public interface IBigBlueButtonInGW {
void getAllMeetings(String meetingID);
void lockSettings(String meetingID, Boolean locked, Map<String, Boolean> lockSettigs);
// Polling
void votePoll(String meetingId, String userId, String pollId, Integer questionId, Integer answerId);
void startPoll(String meetingId, String requesterId, String pollId, String pollType);
void stopPoll(String meetingId, String userId, String pollId);
void showPollResult(String meetingId, String requesterId, String pollId, Boolean show);
// Lock
void initLockSettings(String meetingID, Map<String, Boolean> settings);

View File

@ -0,0 +1,44 @@
package org.bigbluebutton.core.pubsub.receivers;
import org.bigbluebutton.common.messages.*;
import com.google.gson.JsonParser;
import com.google.gson.JsonObject;
import org.bigbluebutton.core.api.IBigBlueButtonInGW;
public class PollingMessageReceiver implements MessageHandler{
private IBigBlueButtonInGW bbbGW;
public PollingMessageReceiver(IBigBlueButtonInGW bbbGW) {
this.bbbGW = bbbGW;
}
@Override
public void handleMessage(String pattern, String channel, String message) {
if (channel.equalsIgnoreCase(MessagingConstants.TO_POLLING_CHANNEL)) {
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 (VotePollUserRequestMessage.VOTE_POLL_REQUEST.equals(messageName)) {
VotePollUserRequestMessage msg = VotePollUserRequestMessage.fromJson(message);
bbbGW.votePoll(msg.meetingId, msg.userId, msg.pollId, msg.questionId, msg.answerId);
} else if (StartPollRequestMessage.START_POLL_REQUEST.equals(messageName)){
StartPollRequestMessage msg = StartPollRequestMessage.fromJson(message);
bbbGW.startPoll(msg.meetingId, msg.requesterId, msg.pollId, msg.pollType);
} else if (StopPollRequestMessage.STOP_POLL_REQUEST.equals(messageName)){
StopPollRequestMessage msg = StopPollRequestMessage.fromJson(message);
bbbGW.stopPoll(msg.meetingId, msg.requesterId, msg.pollId);
} else if (ShowPollResultRequestMessage.SHOW_POLL_RESULT_REQUEST.equals(messageName)){
ShowPollResultRequestMessage msg = ShowPollResultRequestMessage.fromJson(message);
bbbGW.showPollResult(msg.meetingId, msg.requesterId, msg.pollId, msg.show);
}
}
}
}
}
}

View File

@ -31,6 +31,9 @@ public class RedisMessageReceiver {
WhiteboardMessageReceiver whiteboardRx = new WhiteboardMessageReceiver(bbbGW);
receivers.add(whiteboardRx);
PollingMessageReceiver pollRx = new PollingMessageReceiver(bbbGW);
receivers.add(pollRx);
MeetingMessageReceiver meetingRx = new MeetingMessageReceiver(bbbGW);
receivers.add(meetingRx);
}

View File

@ -46,6 +46,7 @@ object Boot extends App with SystemConfiguration {
val presSender = new PresentationEventRedisPublisher(msgSender)
val userSender = new UsersEventRedisPublisher(msgSender)
val whiteboardSender = new WhiteboardEventRedisPublisher(msgSender)
val pollingSender = new PollingEventRedisPublisher(msgSender)
val outMessageListeners = new java.util.ArrayList[OutMessageListener2]()
outMessageListeners.add(chatSender)
@ -57,6 +58,7 @@ object Boot extends App with SystemConfiguration {
outMessageListeners.add(presentationEventRecorder)
outMessageListeners.add(usersEventRecorder)
outMessageListeners.add(whiteboardEventRecorder)
outMessageListeners.add(pollingSender)
val outGW = new MessageOutGateway(outMessageListeners)
val bbbInGW = new BigBlueButtonInGW(system, outGW, voiceEventRecorder)

View File

@ -432,4 +432,25 @@ class BigBlueButtonInGW(val system: ActorSystem, outGW: MessageOutGateway, voice
def voiceRecording(voiceConfId: String, recordingFile: String, timestamp: String, recording: java.lang.Boolean) {
bbbActor ! new VoiceConfRecordingStartedMessage(voiceConfId, recordingFile, recording, timestamp)
}
// Polling
def votePoll(meetingId: String, userId: String, pollId: String, questionId: Integer, answerId: Integer) {
bbbActor ! new RespondToPollRequest(meetingId, userId, pollId, questionId, answerId)
}
def startPoll(meetingId: String, requesterId: String, pollId: String, pollType: String) {
bbbActor ! new StartPollRequest(meetingId, requesterId, pollId, pollType)
}
def stopPoll(meetingId: String, userId: String, pollId: String) {
bbbActor ! new StopPollRequest(meetingId, userId, pollId)
}
def showPollResult(meetingId: String, requesterId: String, pollId: String, show: java.lang.Boolean) {
if (show) {
bbbActor ! new ShowPollResultRequest(meetingId, requesterId, pollId)
} else {
bbbActor ! new HidePollResultRequest(meetingId, requesterId, pollId)
}
}
}

View File

@ -117,7 +117,7 @@ case class PollShowResultMessage(meetingID: String, recorded: Boolean, requester
case class ShowPollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class PollHideResultMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String) extends IOutMessage
case class HidePollResultReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class UserRespondedToPollMessage(meetingID: String, recorded: Boolean, requesterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class UserRespondedToPollMessage(meetingID: String, recorded: Boolean, presenterId: String, pollId: String, poll: SimplePollResultOutVO) extends IOutMessage
case class RespondToPollReplyMessage(meetingID: String, recorded: Boolean, result: RequestResult, requesterId: String, pollId: String) extends IOutMessage
case class GetCurrentPollReplyMessage(meetingID: String, recorded: Boolean, requesterId: String, hasPoll: Boolean, poll: Option[PollVO]) extends IOutMessage

View File

@ -113,8 +113,10 @@ case class Responder(val userId: String, name: String)
case class ResponseOutVO(id: String, text: String, responders: Array[Responder] = Array[Responder]())
case class QuestionOutVO(id: String, multiResponse: Boolean, question: String, responses: Array[ResponseOutVO])
case class SimpleAnswerOutVO(id: Int, key: String)
case class SimplePollOutVO(id: String, answers: Array[SimpleAnswerOutVO])
case class SimpleVoteOutVO(id: Int, key: String, numVotes: Int)
case class SimplePollResultOutVO(id: String, answers: Array[SimpleVoteOutVO])

View File

@ -127,7 +127,10 @@ trait PollApp {
case Some(user) => {
val responder = new Responder(user.userID, user.name)
pollModel.respondToQuestion(poll.id, msg.questionId, msg.answerId, responder)
outGW.send(new UserRespondedToPollMessage(mProps.meetingID, mProps.recorded, msg.requesterId, msg.pollId, poll))
users.getCurrentPresenter foreach { cp =>
outGW.send(new UserRespondedToPollMessage(mProps.meetingID, mProps.recorded, cp.userID, msg.pollId, poll))
}
}
case None => {
val result = new RequestResult(StatusCodes.FORBIDDEN, Some(Array(ErrorCodes.RESOURCE_NOT_FOUND)))

View File

@ -0,0 +1,126 @@
package org.bigbluebutton.core.pubsub.senders
import org.bigbluebutton.core.api.OutMessageListener2
import org.bigbluebutton.core.MessageSender
import org.bigbluebutton.core.api._
import com.google.gson.Gson
import scala.collection.mutable.HashMap
import collection.JavaConverters._
import scala.collection.JavaConversions._
import java.util.ArrayList
import org.bigbluebutton.common.messages.MessagingConstants
import org.bigbluebutton.core.messaging.Util
import org.bigbluebutton.core.apps.SimplePollOutVO
import org.bigbluebutton.core.apps.SimplePollResultOutVO
class PollingEventRedisPublisher(service: MessageSender) extends OutMessageListener2 {
def handleMessage(msg: IOutMessage) {
msg match {
case msg: PollStartedMessage => handlePollStartedMessage(msg)
case msg: PollStoppedMessage => handlePollStoppedMessage(msg)
case msg: PollShowResultMessage => handlePollShowResultMessage(msg)
case msg: PollHideResultMessage => handlePollHideResultMessage(msg)
case msg: UserRespondedToPollMessage => handleUserRespondedToPollMessage(msg)
case _ => // do nothing
}
}
private def handlePollStartedMessage(msg: PollStartedMessage) {
val json = pollStartedMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollStoppedMessage(msg: PollStoppedMessage) {
val json = pollStoppedMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollShowResultMessage(msg: PollShowResultMessage) {
val json = pollShowResultMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handlePollHideResultMessage(msg: PollHideResultMessage) {
val json = pollHideResultMessageToJson(msg)
service.send(MessagingConstants.FROM_POLLING_CHANNEL, json)
}
private def handleUserRespondedToPollMessage(msg: UserRespondedToPollMessage) {
// val json = ChatMessageToJsonConverter.sendPrivateMessageEventToJson(msg)
// service.send(MessagingConstants.FROM_CHAT_CHANNEL, json)
}
private def pollVOtoMap(msg: SimplePollOutVO): java.util.HashMap[String, Object] = {
val pollVO = new java.util.HashMap[String, Object]()
pollVO.put("id", msg.id)
val answers = new java.util.ArrayList[java.util.Map[String, Any]];
msg.answers.foreach(ans => {
val amap = new java.util.HashMap[String, Any]()
amap.put("id", ans.id)
amap.put("key", ans.key)
answers.add(amap)
})
pollVO.put("answers", answers)
pollVO
}
private def pollStartedMessageToJson(msg: PollStartedMessage): String = {
// val payload = new java.util.HashMap[String, Any]()
// payload.put(Constants.MEETING_ID, msg.meetingID)
// payload.put(org.bigbluebutton.common.messages.PollStartedMessage.REQUESTER_ID, msg.requesterId)
// val pollVO = pollVOtoMap(msg.poll)
// payload.put(org.bigbluebutton.common.messages.PollStartedMessage.POLL, pollVO)
// val header = Util.buildHeader(org.bigbluebutton.common.messages.PollStartedMessage.POLL_STARTED, None)
// Util.buildJson(header, payload)
val pollVO = pollVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.PollStartedMessage(msg.meetingID, msg.requesterId, pollVO)
psm.toJson
}
private def pollStoppedMessageToJson(msg: PollStoppedMessage): String = {
val psm = new org.bigbluebutton.common.messages.PollStoppedMessage(msg.meetingID, msg.requesterId, msg.pollId)
psm.toJson
}
private def pollResultVOtoMap(msg: SimplePollResultOutVO): java.util.HashMap[String, Object] = {
val pollVO = new java.util.HashMap[String, Object]()
pollVO.put("id", msg.id)
val answers = new java.util.ArrayList[java.util.Map[String, Any]];
msg.answers.foreach(ans => {
val amap = new java.util.HashMap[String, Any]()
amap.put("id", ans.id)
amap.put("key", ans.key)
amap.put("num_votes", ans.numVotes)
answers.add(amap)
})
pollVO.put("answers", answers)
pollVO
}
private def pollShowResultMessageToJson(msg: PollShowResultMessage): String = {
val pollResultVO = pollResultVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.PollShowResultMessage(msg.meetingID, pollResultVO)
psm.toJson
}
private def pollHideResultMessageToJson(msg: PollHideResultMessage): String = {
val psm = new org.bigbluebutton.common.messages.PollHideResultMessage(msg.meetingID, msg.pollId)
psm.toJson
}
private def UserRespondedToPollMessageTpJson(msg: UserRespondedToPollMessage): String = {
val pollResultVO = pollResultVOtoMap(msg.poll)
val psm = new org.bigbluebutton.common.messages.UserVotedPollMessage(msg.meetingID, msg.presenterId, pollResultVO)
psm.toJson
}
}

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.4",
"org.bigbluebutton" % "bbb-common-message" % "0.0.5",
"org.bigbluebutton" % "bbb-fsesl-client" % "0.0.2"
)}

View File

@ -4,7 +4,7 @@ name := "bbb-common-message"
organization := "org.bigbluebutton"
version := "0.0.5-SNAPSHOT"
version := "0.0.5"
// We want to have our jar files in lib_managed dir.
// This way we'll have the right path when we import
@ -40,11 +40,16 @@ crossPaths := false
// This forbids including Scala related libraries into the dependency
autoScalaLibrary := false
/***************************
* When developing, change the version above to x.x.x-SNAPSHOT then use the file resolver to
* publish to the local maven repo using "sbt publish"
*/
// Uncomment this to publish to local maven repo while commenting out the nexus repo
//publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/.m2/repository")))
publishTo := Some(Resolver.file("file", new File(Path.userHome.absolutePath+"/dev/repo/maven-repo/releases" )) )
// Comment this out when publishing to local maven repo using SNAPSHOT version.
// To push to sonatype "sbt publishSigned"
publishTo := {
val nexus = "https://oss.sonatype.org/"
if (isSnapshot.value)

View File

@ -0,0 +1,59 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class PollHideResultMessage implements ISubscribedMessage {
public static final String POLL_HIDE_RESULT = "poll_hide_result_message";
public static final String VERSION = "0.0.1";
public static final String MEETING_ID = "meeting_id";
public static final String POLL_ID = "poll_id";
public final String meetingId;
public final String pollId;
public PollHideResultMessage(String meetingId, String pollId) {
this.meetingId = meetingId;
this.pollId = pollId;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(MEETING_ID, meetingId);
payload.put(POLL_ID, pollId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(POLL_HIDE_RESULT, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static PollHideResultMessage fromJson(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");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (POLL_HIDE_RESULT.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(POLL_ID)) {
String id = payload.get(Constants.MEETING_ID).getAsString();
String pollId = payload.get(POLL_ID).getAsString();
return new PollHideResultMessage(id, pollId);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,63 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class PollStoppedMessage implements ISubscribedMessage {
public static final String POLL_STOPPED = "poll_stopped_message";
public static final String VERSION = "0.0.1";
public static final String MEETING_ID = "meeting_id";
public static final String REQUESTER_ID = "requester_id";
public static final String POLL_ID = "poll_id";
public final String meetingId;
public final String requesterId;
public final String pollId;
public PollStoppedMessage(String meetingId, String requesterId, String pollId) {
this.meetingId = meetingId;
this.requesterId = requesterId;
this.pollId = pollId;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(MEETING_ID, meetingId);
payload.put(REQUESTER_ID, requesterId);
payload.put(POLL_ID, pollId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(POLL_STOPPED, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static PollStoppedMessage fromJson(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");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (POLL_STOPPED.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(REQUESTER_ID)
&& payload.has(POLL_ID)) {
String id = payload.get(Constants.MEETING_ID).getAsString();
String requesterId = payload.get(REQUESTER_ID).getAsString();
String pollId = payload.get(POLL_ID).getAsString();
return new PollStoppedMessage(id, requesterId, pollId);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,75 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class VotePollUserRequestMessage implements ISubscribedMessage {
public static final String VOTE_POLL_REQUEST = "vote_poll_user_request_message";
public static final String VERSION = "0.0.1";
public static final String MEETING_ID = "meeting_id";
public static final String USER_ID = "user_id";
public static final String POLL_ID = "poll_id";
public static final String QUESTION_ID = "question_id";
public static final String ANSWER_ID = "answer_id";
public final String meetingId;
public final String userId;
public final String pollId;
public final Integer questionId;
public final Integer answerId;
public VotePollUserRequestMessage(String meetingId, String userId, String pollId, Integer questionId, Integer answerId) {
this.meetingId = meetingId;
this.userId = userId;
this.pollId = pollId;
this.questionId = questionId;
this.answerId = answerId;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(MEETING_ID, meetingId);
payload.put(USER_ID, userId);
payload.put(POLL_ID, pollId);
payload.put(QUESTION_ID, questionId);
payload.put(ANSWER_ID, answerId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(VOTE_POLL_REQUEST, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static VotePollUserRequestMessage fromJson(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");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (VOTE_POLL_REQUEST.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(USER_ID)
&& payload.has(POLL_ID)
&& payload.has(QUESTION_ID)
&& payload.has(ANSWER_ID)) {
String id = payload.get(Constants.MEETING_ID).getAsString();
String userId = payload.get(USER_ID).getAsString();
String pollId = payload.get(POLL_ID).getAsString();
Integer questionId = payload.get(QUESTION_ID).getAsInt();
Integer answerId = payload.get(ANSWER_ID).getAsInt();
return new VotePollUserRequestMessage(id, userId, pollId, questionId, answerId);
}
}
}
}
return null;
}
}

View File

@ -23,7 +23,7 @@ repositories {
//url "${System.properties['user.home']}/.ivy2/local"
url "/home/ubuntu/.ivy2/local"
layout "pattern", {
artifact "[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
artifact "[organisation]/[module]/[revision]/[artifact].[ext]"
m2compatible = true
}
}
@ -41,7 +41,7 @@ repositories {
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
@ -112,7 +112,7 @@ dependencies {
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.4'
compile 'org.bigbluebutton:bbb-common-message:0.0.5'
}
test {

View File

@ -0,0 +1,108 @@
package org.bigbluebutton.red5.client;
import java.util.HashMap;
import java.util.Map;
import org.bigbluebutton.common.messages.*;
import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage;
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class PollingClientMessageSender {
private ConnectionInvokerService service;
public PollingClientMessageSender(ConnectionInvokerService service) {
this.service = service;
}
public void handlePollMessage(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();
switch (messageName) {
case PollStartedMessage.POLL_STARTED:
processPollStartedMessage(message);
break;
case PollStoppedMessage.POLL_STOPPED:
processPollStoppedMessage(message);
break;
case PollShowResultMessage.POLL_SHOW_RESULT:
processPollShowResultMessage(message);
break;
case UserVotedPollMessage.USER_VOTED_POLL:
processUserVotedPollMessage(message);
break;
}
}
}
}
private void processPollStartedMessage(String json) {
PollStartedMessage msg = PollStartedMessage.fromJson(json);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("poll", msg.poll);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage b = new BroadcastClientMessage(msg.meetingId, "pollStartedMessage", message);
service.sendMessage(b);
}
}
private void processPollStoppedMessage(String json) {
PollStoppedMessage msg = PollStoppedMessage.fromJson(json);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("pollId", msg.pollId);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage b = new BroadcastClientMessage(msg.meetingId, "pollStoppedMessage", message);
service.sendMessage(b);
}
}
private void processPollShowResultMessage(String json) {
PollShowResultMessage msg = PollShowResultMessage.fromJson(json);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("poll", msg.poll);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
BroadcastClientMessage b = new BroadcastClientMessage(msg.meetingId, "pollShowResultMessage", message);
service.sendMessage(b);
}
}
private void processUserVotedPollMessage(String json) {
UserVotedPollMessage msg = UserVotedPollMessage.fromJson(json);
if (msg != null) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("poll", msg.poll);
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args));
DirectClientMessage b = new DirectClientMessage(msg.meetingId, msg.presenterId, "pollUserVotedMessage", message);
service.sendMessage(b);
}
}
}

View File

@ -1,52 +1,8 @@
package org.bigbluebutton.red5.pubsub;
import java.util.Map;
import org.bigbluebutton.common.messages.AssignPresenterRequestMessage;
import org.bigbluebutton.common.messages.BroadcastLayoutRequestMessage;
import org.bigbluebutton.common.messages.ClearWhiteboardRequestMessage;
import org.bigbluebutton.common.messages.EjectUserFromMeetingRequestMessage;
import org.bigbluebutton.common.messages.EjectUserFromVoiceRequestMessage;
import org.bigbluebutton.common.messages.EnableWhiteboardRequestMessage;
import org.bigbluebutton.common.messages.GetChatHistoryRequestMessage;
import org.bigbluebutton.common.messages.GetCurrentLayoutRequestMessage;
import org.bigbluebutton.common.messages.GetLockSettingsMessage;
import org.bigbluebutton.common.messages.GetPresentationInfoMessage;
import org.bigbluebutton.common.messages.GetRecordingStatusRequestMessage;
import org.bigbluebutton.common.messages.GetSlideInfoMessage;
import org.bigbluebutton.common.messages.GetUsersRequestMessage;
import org.bigbluebutton.common.messages.GoToSlideMessage;
import org.bigbluebutton.common.messages.InitAudioSettingsMessage;
import org.bigbluebutton.common.messages.InitPermissionsSettingMessage;
import org.bigbluebutton.common.messages.IsMeetingMutedRequestMessage;
import org.bigbluebutton.common.messages.IsWhiteboardEnabledRequestMessage;
import org.bigbluebutton.common.messages.LockLayoutRequestMessage;
import org.bigbluebutton.common.messages.LockMuteUserRequestMessage;
import org.bigbluebutton.common.messages.LockUserMessage;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.MuteAllExceptPresenterRequestMessage;
import org.bigbluebutton.common.messages.MuteAllRequestMessage;
import org.bigbluebutton.common.messages.MuteUserRequestMessage;
import org.bigbluebutton.common.messages.RemovePresentationMessage;
import org.bigbluebutton.common.messages.RequestWhiteboardAnnotationHistoryRequestMessage;
import org.bigbluebutton.common.messages.ResizeAndMoveSlideMessage;
import org.bigbluebutton.common.messages.SendConversionCompletedMessage;
import org.bigbluebutton.common.messages.SendConversionUpdateMessage;
import org.bigbluebutton.common.messages.SendCursorUpdateMessage;
import org.bigbluebutton.common.messages.SendLockSettingsMessage;
import org.bigbluebutton.common.messages.SendPageCountErrorMessage;
import org.bigbluebutton.common.messages.SendPrivateChatMessage;
import org.bigbluebutton.common.messages.SendPublicChatMessage;
import org.bigbluebutton.common.messages.SendSlideGeneratedMessage;
import org.bigbluebutton.common.messages.SendWhiteboardAnnotationRequestMessage;
import org.bigbluebutton.common.messages.SetRecordingStatusRequestMessage;
import org.bigbluebutton.common.messages.SetUserStatusRequestMessage;
import org.bigbluebutton.common.messages.SharePresentationMessage;
import org.bigbluebutton.common.messages.UserLeavingMessage;
import org.bigbluebutton.common.messages.UserLoweredHandMessage;
import org.bigbluebutton.common.messages.UserRaisedHandMessage;
import org.bigbluebutton.common.messages.UserShareWebcamRequestMessage;
import org.bigbluebutton.common.messages.UserUnshareWebcamRequestMessage;
import org.bigbluebutton.common.messages.ValidateAuthTokenMessage;
import org.bigbluebutton.common.messages.*;
import org.bigbluebutton.red5.pubsub.redis.MessageSender;
public class MessagePublisher {
@ -57,6 +13,27 @@ public class MessagePublisher {
this.sender = sender;
}
// Polling
public void votePoll(String meetingId, String userId, String pollId, Integer questionId, Integer answerId) {
VotePollUserRequestMessage msg = new VotePollUserRequestMessage(meetingId, userId, pollId, questionId, answerId);
sender.send(MessagingConstants.TO_POLLING_CHANNEL, msg.toJson());
}
public void startPoll(String meetingId, String requesterId, String pollId, String pollType) {
StartPollRequestMessage msg = new StartPollRequestMessage(meetingId, requesterId, pollId, pollType);
sender.send(MessagingConstants.TO_POLLING_CHANNEL, msg.toJson());
}
public void stopPoll(String meetingId, String userId, String pollId) {
StopPollRequestMessage msg = new StopPollRequestMessage(meetingId, userId, pollId);
sender.send(MessagingConstants.TO_POLLING_CHANNEL, msg.toJson());
}
public void showPollResult(String meetingId, String requesterId, String pollId, Boolean show) {
ShowPollResultRequestMessage msg = new ShowPollResultRequestMessage(meetingId, requesterId, pollId, show);
sender.send(MessagingConstants.TO_POLLING_CHANNEL, msg.toJson());
}
public void initLockSettings(String meetingID, Map<String, Boolean> permissions) {
InitPermissionsSettingMessage msg = new InitPermissionsSettingMessage(meetingID, permissions);
sender.send(MessagingConstants.TO_USERS_CHANNEL, msg.toJson());

View File

@ -2,6 +2,7 @@ package org.bigbluebutton.red5.pubsub.redis;
import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.red5.client.MeetingClientMessageSender;
import org.bigbluebutton.red5.client.PollingClientMessageSender;
import org.bigbluebutton.red5.client.PresentationClientMessageSender;
import org.bigbluebutton.red5.client.UserClientMessageSender;
import org.bigbluebutton.red5.client.ChatClientMessageSender;
@ -18,7 +19,7 @@ public class RedisPubSubMessageHandler implements MessageHandler {
private PresentationClientMessageSender presentationMessageSender;
private WhiteboardClientMessageSender whiteboardMessageSender;
private BbbAppsIsKeepAliveHandler bbbAppsIsKeepAliveHandler;
private PollingClientMessageSender pollingMessageSender;
public void setConnectionInvokerService(ConnectionInvokerService s) {
this.service = s;
@ -27,6 +28,7 @@ public class RedisPubSubMessageHandler implements MessageHandler {
chatMessageSender = new ChatClientMessageSender(service);
presentationMessageSender = new PresentationClientMessageSender(service);
whiteboardMessageSender = new WhiteboardClientMessageSender(service);
pollingMessageSender = new PollingClientMessageSender(service);
}
public void setBbbAppsIsKeepAliveHandler(BbbAppsIsKeepAliveHandler handler) {
@ -47,6 +49,8 @@ public class RedisPubSubMessageHandler implements MessageHandler {
whiteboardMessageSender.handleWhiteboardMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.BBB_APPS_KEEP_ALIVE_CHANNEL)) {
bbbAppsIsKeepAliveHandler.handleKeepAliveMessage(message);
} else if (channel.equalsIgnoreCase(MessagingConstants.FROM_POLLING_CHANNEL)) {
pollingMessageSender.handlePollMessage(message);
}
}

View File

@ -0,0 +1,107 @@
/**
* 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/>.
* Author: Felipe Cecagno <felipe@mconf.org>
*/
package org.bigbluebutton.red5.service;
import java.util.Map;
import org.bigbluebutton.red5.BigBlueButtonSession;
import org.bigbluebutton.red5.Constants;
import org.bigbluebutton.red5.pubsub.MessagePublisher;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.Red5;
import org.slf4j.Logger;
public class PollingService {
private static Logger log = Red5LoggerFactory.getLogger( PollingService.class, "bigbluebutton" );
private MessagePublisher red5GW;
public void setRed5Publisher(MessagePublisher inGW) {
red5GW = inGW;
}
public void votePoll(Map<String, Object> message) {
log.debug("Received broadcast layout request");
String meetingID = Red5.getConnectionLocal().getScope().getName();
String userId = getBbbSession().getInternalUserID();
String pollId = (String) message.get("pollId");
Integer questionId = (Integer) message.get("questionId");
Integer answerId = (Integer) message.get("answerId");
// red5GW.broadcastLayout(meetingID, getBbbSession().getInternalUserID(), newlayout);
}
public void showPollResult(Map<String, Object> message) {
log.debug("Received broadcast layout request");
String meetingID = Red5.getConnectionLocal().getScope().getName();
String newlayout = (String) message.get("layout");
if (newlayout == null || newlayout.isEmpty()) {
log.error("Invalid Broadcast Layout message. layout is null or empty.");
return;
}
red5GW.broadcastLayout(meetingID, getBbbSession().getInternalUserID(), newlayout);
}
public void startPoll(Map<String, Object> message) {
log.debug("Received broadcast layout request");
String meetingID = Red5.getConnectionLocal().getScope().getName();
String newlayout = (String) message.get("layout");
if (newlayout == null || newlayout.isEmpty()) {
log.error("Invalid Broadcast Layout message. layout is null or empty.");
return;
}
red5GW.broadcastLayout(meetingID, getBbbSession().getInternalUserID(), newlayout);
}
public void stopPoll(Map<String, Object> message) {
log.debug("Received lock layout request");
String meetingID = Red5.getConnectionLocal().getScope().getName();
String newlayout = (String) message.get("layout");
Boolean lock = (Boolean) message.get("lock");
Boolean viewersOnly = (Boolean) message.get("viewersOnly");
String layout;
if (newlayout == null || newlayout.isEmpty()) {
layout = null;
} else {
layout = newlayout;
}
if (lock == null) {
log.error("Invalid Lock Layout message. lock in null.");
return;
}
if (viewersOnly == null) {
log.error("Invalid Lock Layout message. viewersOnly is null");
return;
}
red5GW.lockLayout(meetingID, getBbbSession().getInternalUserID(), lock, viewersOnly, layout);
}
private BigBlueButtonSession getBbbSession() {
return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION);
}
}

View File

@ -1,23 +0,0 @@
akka {
actor {
debug {
receive = on
}
}
loglevel = DEBUG
stdout-loglevel = "DEBUG"
}
spray.can.server {
request-timeout = 10s
}
service {
host = "192.168.153.144"
port = 8989
}
api {
channel = "bbb-apps-channel"
source = "bigbluebutton-apps"
}

View File

@ -87,6 +87,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<property name="red5Publisher"> <ref bean="red5Publisher"/></property>
</bean>
<bean id="poll.service" class="org.bigbluebutton.red5.service.PollingService">
<property name="red5Publisher"> <ref bean="red5Publisher"/></property>
</bean>
<bean id="whiteboard.service" class="org.bigbluebutton.red5.service.WhiteboardService">
<property name="whiteboardApplication"> <ref local="whiteboardApplication"/></property>
</bean>