- broadcast messages to other clients without using shared object

This commit is contained in:
Richard Alam 2012-07-13 20:30:32 +00:00
parent 5b55b6930b
commit 45faed3019
7 changed files with 122 additions and 118 deletions

View File

@ -71,6 +71,7 @@ public class ConnectionInvokerService {
IScope scope = scopes.get(message.getDest());
if (scope != null) {
List<Object> params = new ArrayList<Object>();
params.add(message.getMessageName());
params.add(message.getMessage());
ServiceUtils.invokeOnAllConnections(scope, "onMessageFromServer", params.toArray());
}

View File

@ -1,15 +1,11 @@
package org.bigbluebutton.conference.service.recorder.whiteboard;
import java.util.HashMap;
import java.util.Map;
import org.bigbluebutton.conference.service.recorder.Recorder;
import org.bigbluebutton.conference.service.recorder.RecorderApplication;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.bigbluebutton.conference.service.whiteboard.IWhiteboardRoomListener;
import org.bigbluebutton.conference.service.whiteboard.Presentation;
import org.bigbluebutton.conference.service.whiteboard.Shape;
public class WhiteboardEventRecorder implements IWhiteboardRoomListener{
private static Logger log = Red5LoggerFactory.getLogger( WhiteboardEventRecorder.class, "bigbluebutton" );

View File

@ -25,12 +25,10 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bigbluebutton.conference.BigBlueButtonSession;
import org.bigbluebutton.conference.ClientMessage;
import org.bigbluebutton.conference.ConnectionInvokerService;
import org.bigbluebutton.conference.Constants;
import org.red5.compatibility.flex.messaging.io.ArrayCollection;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.adapter.IApplication;
import org.red5.server.adapter.MultiThreadedApplicationAdapter;
@ -55,22 +53,22 @@ public class WhiteboardApplication extends MultiThreadedApplicationAdapter imple
private ConnectionInvokerService connInvokerService;
@Override
public boolean appStart(IScope app){
public boolean appStart(IScope app) {
log.info("Starting Whiteboard Application");
this.scope = app;
return true;
}
public void setRoomManager(WhiteboardRoomManager manager){
public void setRoomManager(WhiteboardRoomManager manager) {
this.roomManager = manager;
}
@Override
public void appStop(IScope scope){
public void appStop(IScope scope) {
roomManager.removeRoom(getLocalScope().getName());
}
public void setActivePresentation(String name, int numPages){
public void setActivePresentation(String name, int numPages) {
WhiteboardRoom room = roomManager.getRoom(getLocalScope().getName());
if (room.presentationExists(name)) {
room.setActivePresentation(name);
@ -79,62 +77,62 @@ public class WhiteboardApplication extends MultiThreadedApplicationAdapter imple
}
}
public void enableWhiteboard(boolean enabled){
public void enableWhiteboard(boolean enabled) {
roomManager.getRoom(getLocalScope().getName()).setWhiteboardEnabled(enabled);
ISharedObject drawSO = getSharedObject(getLocalScope(), WHITEBOARD_SHARED_OBJECT);
List<Boolean> arguments = new ArrayList<Boolean>();
arguments.add(enabled);
drawSO.sendMessage("modifyEnabledCallback", arguments);
}
public boolean isWhiteboardEnabled(){
return roomManager.getRoom(getLocalScope().getName()).isWhiteboardEnabled();
}
// ISharedObject drawSO = getSharedObject(getLocalScope(), WHITEBOARD_SHARED_OBJECT);
// List<Boolean> arguments = new ArrayList<Boolean>();
// arguments.add(enabled);
// drawSO.sendMessage("modifyEnabledCallback", arguments);
public void sendAnnotationHistory(String userid) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("type", "pencil");
ClientMessage m = new ClientMessage(ClientMessage.DIRECT, userid, "receiveAnnotationHistory", message);
message.put("enabled", roomManager.getRoom(getLocalScope().getName()).isWhiteboardEnabled());
ClientMessage m = new ClientMessage(ClientMessage.BROADCAST, getLocalScope().getName(), "EnableWhiteboardCommand", message);
connInvokerService.sendMessage(m);
}
/*
public void sendShape(double[] shape, String type, int color, int thickness, String id, String status){
Shape newShape = new Shape(shape, type, color, thickness, id, status);
roomManager.getRoom(getLocalScope().getName()).addShape(newShape);
ISharedObject drawSO = getSharedObject(getLocalScope(), WHITEBOARD_SHARED_OBJECT);
List<Object> arguments = newShape.toList();
drawSO.sendMessage("addSegment", arguments);
public void isWhiteboardEnabled(String userid) {
Map<String, Object> message = new HashMap<String, Object>();
message.put("enabled", roomManager.getRoom(getLocalScope().getName()).isWhiteboardEnabled());
ClientMessage m = new ClientMessage(ClientMessage.DIRECT, userid, "IsWhiteboardEnabledReply", message);
connInvokerService.sendMessage(m);
}
*/
public void sendAnnotation(Map<String, Object> annotation) {
ISharedObject drawSO = getSharedObject(getLocalScope(), WHITEBOARD_SHARED_OBJECT);
roomManager.getRoom(getLocalScope().getName()).addAnnotation(annotation);
List<Object> arguments = new ArrayList<Object>();
arguments.add(annotation);
drawSO.sendMessage("receiveAnnotation", arguments);
public void sendAnnotationHistory(String userid) {
Map<String, Object> message = new HashMap<String, Object>();
List<Map<String, Object>> annotations = roomManager.getRoom(getLocalScope().getName()).getAnnotations();
message.put("count", new Integer(annotations.size()));
message.put("annotations", annotations);
ClientMessage m = new ClientMessage(ClientMessage.DIRECT, userid, "RequestAnnotationHistoryReply", message);
connInvokerService.sendMessage(m);
}
public int getNumShapesOnPage(int pageNum){
public void sendAnnotation(Map<String, Object> annotation) {
// ISharedObject drawSO = getSharedObject(getLocalScope(), WHITEBOARD_SHARED_OBJECT);
// roomManager.getRoom(getLocalScope().getName()).addAnnotation(annotation);
// List<Object> arguments = new ArrayList<Object>();
// arguments.add(annotation);
// drawSO.sendMessage("receiveAnnotation", arguments);
Map<String, Object> message = new HashMap<String, Object>();
roomManager.getRoom(getLocalScope().getName()).addAnnotation(annotation);
message.put("annotation", annotation);
ClientMessage m = new ClientMessage(ClientMessage.BROADCAST, getLocalScope().getName(), "NewAnnotationCommand", annotation);
connInvokerService.sendMessage(m);
}
public int getNumShapesOnPage(int pageNum) {
Presentation pres = roomManager.getRoom(getLocalScope().getName()).getActivePresentation();
pres.setActivePage(pageNum);
return pres.getActivePage().getNumShapesOnPage();
}
public List<Map<String, Object>> getShapes(){
List<Map<String, Object>> shapesList = roomManager.getRoom(getLocalScope().getName()).getShapes();
return shapesList;
}
public void clear(){
public void clear() {
roomManager.getRoom(getLocalScope().getName()).clear();
ISharedObject drawSO = getSharedObject(getLocalScope(), WHITEBOARD_SHARED_OBJECT);
drawSO.sendMessage("clear", new ArrayList<Object>());
}
public void undo(){
public void undo() {
roomManager.getRoom(getLocalScope().getName()).undo();
ISharedObject drawSO = getSharedObject(getLocalScope(), WHITEBOARD_SHARED_OBJECT);
drawSO.sendMessage("undo", new ArrayList<Object>());

View File

@ -26,9 +26,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bigbluebutton.conference.service.chat.IChatRoomListener;
import org.red5.compatibility.flex.messaging.io.ArrayCollection;
import org.red5.server.api.IScope;
public class WhiteboardRoom {
@ -50,6 +47,7 @@ public class WhiteboardRoom {
public IScope getScope(){
return this.scope;
}
/**
* Add a new presentation. Will also set the activePresentation
@ -97,7 +95,7 @@ public class WhiteboardRoom {
notifyAddShape(activePresentation, annotation);
}
public List<Map<String, Object>> getShapes(){
public List<Map<String, Object>> getAnnotations(){
return activePresentation.getActivePage().getShapes();
}

View File

@ -22,10 +22,7 @@
package org.bigbluebutton.conference.service.whiteboard;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.red5.compatibility.flex.messaging.io.ArrayCollection;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.Red5;
import org.slf4j.Logger;
@ -47,18 +44,18 @@ public class WhiteboardService {
}
public void sendAnnotation(Map<String, Object> annotation) {
for (Map.Entry<String, Object> entry : annotation.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// for (Map.Entry<String, Object> entry : annotation.entrySet()) {
// String key = entry.getKey();
// Object value = entry.getValue();
if (key.equals("points")) {
String points = "points=[";
ArrayList<Double> v = (ArrayList<Double>) value;
log.debug(points + pointsToString(v) + "]");
} else {
log.debug(key + "=[" + value + "]");
}
}
// if (key.equals("points")) {
// String points = "points=[";
// ArrayList<Double> v = (ArrayList<Double>) value;
// log.debug(points + pointsToString(v) + "]");
// } else {
// log.debug(key + "=[" + value + "]");
// }
// }
application.sendAnnotation(annotation);
}
@ -69,7 +66,7 @@ public class WhiteboardService {
datapoints += i + ",";
}
// Trim the trailing comma
log.debug("Data Point = " + datapoints);
// log.debug("Data Point = " + datapoints);
return datapoints.substring(0, datapoints.length() - 1);
}
@ -84,23 +81,9 @@ public class WhiteboardService {
return 1; //application.getNumShapesOnPage(pageNum);
}
//public List<Map<String, Object>> getShapes(){
public void getShapes(){
log.info("WhiteboardApplication - Returning shapes");
List<Map<String, Object>> shapes = application.getShapes();
public void requestAnnotationHistory() {
log.info("WhiteboardApplication - requestAnnotationHistory");
application.sendAnnotationHistory(Red5.getConnectionLocal().getClient().getId());
/*System.out.println("Number of shapes: " + shapes.size());
System.out.println("First shape. Num params: " + shapes.get(0).length);
System.out.println("double[] : " + (double[])shapes.get(0)[0]);
System.out.println("type : " + shapes.get(0)[1]);
System.out.println("color : " + shapes.get(0)[2]);
System.out.println("thickness : " + shapes.get(0)[3]);
System.out.println("parentWidth : " + shapes.get(0)[4]);
System.out.println("parentHeight : " + shapes.get(0)[5]);*/
//return shapes;
}
public void clear(){
@ -123,8 +106,8 @@ public class WhiteboardService {
application.enableWhiteboard(enable);
}
public boolean isWhiteboardEnabled(){
return application.isWhiteboardEnabled();
public void isWhiteboardEnabled(){
application.isWhiteboardEnabled(Red5.getConnectionLocal().getClient().getId());
}
}

View File

@ -102,7 +102,49 @@ package org.bigbluebutton.modules.whiteboard.business
public function onMessage(messageName:String, message:Object):void {
LogUtil.debug("WB: received message " + messageName);
switch (messageName) {
case "RequestAnnotationHistoryReply":
handleRequestAnnotationHistoryReply(message);
break;
case "IsWhiteboardEnabledReply":
handleIsWhiteboardEnabledReply(message);
break;
case "EnableWhiteboardCommand":
handleEnableWhiteboardCommand(message);
break;
case "NewAnnotationCommand":
handleNewAnnotationCommand(message);
break;
default:
LogUtil.warn("Cannot handle message [" + messageName + "]");
}
}
private function handleEnableWhiteboardCommand(message:Object):void {
//if (result as Boolean) modifyEnabledCallback(true);
LogUtil.debug("Handle Whiteboard Enabled Command " + message.enabled);
}
private function handleNewAnnotationCommand(message:Object):void {
LogUtil.debug("Handle new annotation[" + message.type + ", " + message.id + ", " + message.status + "]");
}
private function handleIsWhiteboardEnabledReply(message:Object):void {
//if (result as Boolean) modifyEnabledCallback(true);
LogUtil.debug("Whiteboard Enabled? " + message.enabled);
}
private function handleRequestAnnotationHistoryReply(message:Object):void {
if (message.count == 0) {
LogUtil.debug("No annotations.");
} else {
LogUtil.debug("Number of annotations in history = " + message.count);
}
}
/**
* Once a shared object is created, it is synced accross all clients, and this method is invoked
@ -134,7 +176,7 @@ package org.bigbluebutton.modules.whiteboard.business
); //_netConnection.call
}
public function checkIsWhiteboardOn():void{
public function checkIsWhiteboardOn():void {
var nc:NetConnection = connection;
nc.call(
"whiteboard.isWhiteboardEnabled",// Remote function name
@ -142,7 +184,7 @@ package org.bigbluebutton.modules.whiteboard.business
// On successful result
function(result:Object):void {
LogUtil.debug("Whiteboard::checkIsWhiteboardOn() : " + result as String);
if (result as Boolean) modifyEnabledCallback(true);
// if (result as Boolean) modifyEnabledCallback(true);
},
// status - On error occurred
function(status:Object):void {
@ -156,24 +198,21 @@ package org.bigbluebutton.modules.whiteboard.business
); //_netConnection.call
}
public function getPageHistory(e:PageEvent):void{
public function getPageHistory(e:PageEvent):void {
var nc:NetConnection = connection;
nc.call(
"whiteboard.setActivePage",// Remote function name
new Responder(
// On successful result
function(result:Object):void {
nc.call("whiteboard.setActivePage",
new Responder(
function(result:Object):void { // On successful result
if ((result as int) != e.shapes.length) {
LogUtil.debug("Whiteboard: Need to retrieve shapes. Have " + e.shapes.length + " on client, "
+ (result as int) + " on server");
LogUtil.debug("Whiteboard: Need to retrieve shapes. Have " + e.shapes.length + " on client, " + (result as int) + " on server");
LogUtil.debug("Whiteboard: Retrieving shapes on page" + e.pageNum);
getHistory();
} else{
LogUtil.debug("Whiteboard: Shapes up to date, no need to update");
}
},
// status - On error occurred
function(status:Object):void {
function(status:Object):void { // status - On error occurred
LogUtil.error("Error occurred: Whiteboard::DrawProxy::getPageHistory()");
for (var x:Object in status) {
LogUtil.error(x + " : " + status[x]);
@ -254,13 +293,7 @@ package org.bigbluebutton.modules.whiteboard.business
dispatcher.dispatchEvent(e);
}
public function receiveAnnotation(annotation:Object):void {
for(var id:String in annotation) {
var value:Object = annotation[id];
LogUtil.debug(id + " = " + value);
}
}
/**
* Sends a call out to the red5 server to notify the clients that the board needs to be cleared
@ -362,7 +395,7 @@ package org.bigbluebutton.modules.whiteboard.business
private function getHistory():void{
var nc:NetConnection = connection;
nc.call(
"whiteboard.getShapes",// Remote function name
"whiteboard.requestAnnotationHistory",// Remote function name
new Responder(
// On successful result
function(result:Object):void {
@ -381,10 +414,6 @@ package org.bigbluebutton.modules.whiteboard.business
); //_netConnection.call
}
public function receiveAnnotationHistory(result:Object):void {
LogUtil.debug("Got annotation history");
}
private function receivedShapesHistory(result:Object):void{
if (result == null) return;

View File

@ -33,8 +33,7 @@ package org.bigbluebutton.modules.whiteboard.managers
public class PageManager
{
private var pageNum:int;
private var pages:ArrayCollection;
private var pages:ArrayCollection;
private var dispatcher:Dispatcher;
public function PageManager()
@ -44,21 +43,21 @@ package org.bigbluebutton.modules.whiteboard.managers
dispatcher = new Dispatcher();
}
public function addShapeToPage(e:WhiteboardUpdate):void{
public function addShapeToPage(e:WhiteboardUpdate):void {
(pages.getItemAt(pageNum) as ArrayCollection).addItem(e.data);
}
public function undoShapeFromPage():void{
public function undoShapeFromPage():void {
var page:ArrayCollection = pages.getItemAt(pageNum) as ArrayCollection;
if (page.length > 0) page.removeItemAt(page.length - 1);
}
public function clearPage():void{
public function clearPage():void {
var page:ArrayCollection = pages.getItemAt(pageNum) as ArrayCollection;
page.removeAll();
}
public function loadPage(e:PageEvent):void{
public function loadPage(e:PageEvent):void {
if (pages.length ==0 ) return;
if ((pages.getItemAt(e.pageNum) as ArrayCollection).length == 0) return;
@ -67,15 +66,15 @@ package org.bigbluebutton.modules.whiteboard.managers
timer.start();
}
private function defferedLoad(e:TimerEvent):void{
private function defferedLoad(e:TimerEvent):void {
gotoPage(this.pageNum);
}
public function changePage(e:NavigationEvent):void{
public function changePage(e:NavigationEvent):void {
gotoPage(e.pageNumber);
}
private function gotoPage(pageNumber:int):void{
private function gotoPage(pageNumber:int):void {
if (pages == null || pages.length < pageNumber) return;
var event:PageEvent = new PageEvent(PageEvent.CHANGE_PAGE);
@ -85,7 +84,7 @@ package org.bigbluebutton.modules.whiteboard.managers
dispatcher.dispatchEvent(event);
}
public function createPages(e:PresentationEvent):void{
public function createPages(e:PresentationEvent):void {
pages.removeAll();
for (var i:int = 0; i<e.numberOfSlides; i++){
pages.addItem(new ArrayCollection());