Merge pull request #665 from ritzalam/implement-polling-v3
Implement polling v3
This commit is contained in:
commit
84446f93fa
@ -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"
|
||||
)}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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])
|
||||
|
||||
|
@ -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)))
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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"
|
||||
)}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user