2013-10-31 04:04:43 +08:00
|
|
|
_ = require("lodash")
|
|
|
|
redis = require("redis")
|
|
|
|
|
|
|
|
config = require("../config")
|
|
|
|
Logger = require("./logger")
|
|
|
|
Utils = require("./utils")
|
2014-02-28 03:53:58 +08:00
|
|
|
messageLib = require("bigbluebutton-messages")
|
2013-10-31 04:04:43 +08:00
|
|
|
|
|
|
|
moduleDeps = ["RedisAction"]
|
|
|
|
|
|
|
|
# A module that publishes messages to redis.
|
|
|
|
module.exports = class RedisPublisher
|
|
|
|
|
|
|
|
constructor: ->
|
|
|
|
config.modules.wait moduleDeps, =>
|
|
|
|
@redisAction = config.modules.get("RedisAction")
|
|
|
|
@pub = redis.createClient()
|
|
|
|
|
2014-02-20 00:00:17 +08:00
|
|
|
# Publish list of shapes to appropriate clients
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishShapes2: (meetingID, sessionID, callback) ->
|
|
|
|
shapes = []
|
|
|
|
@redisAction.getCurrentPresentationID meetingID, (err, presentationID) =>
|
|
|
|
@redisAction.getCurrentPageID meetingID, presentationID, (err, pageID) =>
|
|
|
|
@redisAction.getItems meetingID, presentationID, pageID, "currentshapes", (err, shapes) =>
|
|
|
|
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
allShapesEventObject = {
|
|
|
|
name : "allShapes",
|
|
|
|
shapes : shapes
|
|
|
|
}
|
|
|
|
@pub.publish receivers, JSON.stringify(allShapesEventObject)
|
|
|
|
callback?(null)
|
|
|
|
|
2014-02-28 03:53:58 +08:00
|
|
|
|
2013-12-18 03:51:46 +08:00
|
|
|
# Publish load users to appropriate clients.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishLoadUsers2: (meetingID, sessionID, callback) ->
|
|
|
|
console.log("***publishLoadUsers2***")
|
|
|
|
usernames = []
|
|
|
|
@redisAction.getUsers meetingID, (err, users) =>
|
2014-04-04 22:26:09 +08:00
|
|
|
|
2014-03-31 23:45:32 +08:00
|
|
|
console.log "___users.length=" + users.length
|
2013-12-18 03:51:46 +08:00
|
|
|
users.forEach (user) =>
|
2014-03-31 23:45:32 +08:00
|
|
|
if user?
|
|
|
|
usernames.push
|
|
|
|
name: user.username
|
|
|
|
id: user.pubID
|
2013-12-18 03:51:46 +08:00
|
|
|
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
|
|
|
|
loadUsersEventObject = {
|
|
|
|
name: "loadUsers",
|
|
|
|
meeting : {
|
|
|
|
id: meetingID,
|
|
|
|
sessionID : sessionID
|
|
|
|
},
|
|
|
|
usernames : usernames
|
|
|
|
}
|
|
|
|
|
|
|
|
@pub.publish "bigbluebutton:bridge", JSON.stringify(loadUsersEventObject)
|
|
|
|
callback?(null, true)
|
|
|
|
|
|
|
|
|
2013-10-31 04:04:43 +08:00
|
|
|
|
|
|
|
# Publish the current presenter's public ID to appropriate clients.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishPresenter: (meetingID, sessionID, callback) ->
|
|
|
|
@redisAction.getPresenterPublicID meetingID, (err, publicID) =>
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
@pub.publish receivers, JSON.stringify(["setPresenter", publicID])
|
|
|
|
callback?(null, true)
|
|
|
|
|
2013-11-12 06:55:39 +08:00
|
|
|
# Publishes a user join.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishUserJoin2: (meetingID, sessionID, userid, username, callback) ->
|
2014-04-04 22:26:09 +08:00
|
|
|
console.log ("**publishUserJoin2**")
|
2014-04-04 02:34:19 +08:00
|
|
|
|
|
|
|
sessionID = "someSessionID" unless sessionID?
|
|
|
|
|
|
|
|
userJoinEventObject = {
|
|
|
|
header: {
|
|
|
|
destination: {
|
|
|
|
to: "apps_channel"
|
|
|
|
},
|
|
|
|
name: "user_joined_event",
|
|
|
|
timestamp: "Thu, 03 Apr 2014 16:06:38 GMT",
|
|
|
|
source: "bbb-web"
|
|
|
|
},
|
|
|
|
payload: {
|
|
|
|
meeting: {
|
|
|
|
name: "someMeetingName",
|
|
|
|
id: meetingID
|
|
|
|
},
|
|
|
|
session: sessionID,
|
|
|
|
user: {
|
|
|
|
id: userid,
|
|
|
|
external_id: "external_id",
|
|
|
|
name: username,
|
|
|
|
role: "MODERATOR",
|
|
|
|
pin: 12345,
|
|
|
|
welcome_message: "Welcome to English 101",
|
|
|
|
logout_url: "http://www.example.com",
|
|
|
|
avatar_url: "http://www.example.com/avatar.png",
|
|
|
|
is_presenter: true,
|
|
|
|
status: {
|
|
|
|
hand_raised: false,
|
|
|
|
muted: false,
|
|
|
|
locked: false,
|
|
|
|
talking: false
|
|
|
|
},
|
|
|
|
caller_id: {
|
|
|
|
name: "Juan Tamad",
|
|
|
|
number: "011-63-917-555-1234"
|
|
|
|
},
|
|
|
|
media_streams: [
|
|
|
|
{
|
|
|
|
media_type: "audio",
|
|
|
|
uri: "http://cdn.bigbluebutton.org/stream/a1234",
|
|
|
|
metadata: {
|
|
|
|
foo: "bar"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
media_type: "video",
|
|
|
|
uri: "http://cdn.bigbluebutton.org/stream/v1234",
|
|
|
|
metadata: {
|
|
|
|
foo: "bar"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
media_type: "screen",
|
|
|
|
uri: "http://cdn.bigbluebutton.org/stream/s1234",
|
|
|
|
metadata: {
|
|
|
|
foo: "bar"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
metadata: {
|
|
|
|
student_id: "54321",
|
|
|
|
program: "engineering"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-11-12 06:55:39 +08:00
|
|
|
}
|
2013-11-13 06:21:11 +08:00
|
|
|
@pub.publish "bigbluebutton:bridge", JSON.stringify( userJoinEventObject )
|
|
|
|
|
2013-11-12 06:55:39 +08:00
|
|
|
callback?(null, true)
|
|
|
|
|
2013-12-10 05:47:11 +08:00
|
|
|
# Get all chat messages from redis and publish to the appropriate clients
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
# @todo callback should be called at the end and only once, can use async for this
|
|
|
|
publishMessages2: (meetingID, sessionID, callback) ->
|
|
|
|
messages = []
|
|
|
|
@redisAction.getCurrentPresentationID meetingID, (err, presentationID) =>
|
|
|
|
@redisAction.getCurrentPageID meetingID, presentationID, (err, pageID) =>
|
|
|
|
@redisAction.getItems meetingID, presentationID, pageID, "messages", (err, messages) =>
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
allMessagesEventObject = {
|
|
|
|
name: "all_messages",
|
|
|
|
meeting: {
|
|
|
|
id:meetingID,
|
|
|
|
sessionID:sessionID
|
|
|
|
},
|
|
|
|
messages:messages
|
|
|
|
|
|
|
|
}
|
|
|
|
@pub.publish receivers, JSON.stringify( allMessagesEventObject )
|
|
|
|
callback?(true)
|
|
|
|
|
2013-11-19 03:36:27 +08:00
|
|
|
# Publish list of slides from redis to the appropriate clients
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
# @todo callback should be called at the end and only once, can use async for this
|
|
|
|
publishSlides2: (meetingID, sessionID, callback) ->
|
|
|
|
console.log("\n\n***publishSlides2 called");
|
|
|
|
slides = []
|
|
|
|
@redisAction.getCurrentPresentationID meetingID, (err, presentationID) =>
|
|
|
|
@redisAction.getPageIDs meetingID, presentationID, (err, pageIDs) =>
|
|
|
|
slideCount = 0
|
|
|
|
pageIDs.forEach (pageID) =>
|
|
|
|
@redisAction.getPageImage meetingID, presentationID, pageID, (err, filename) =>
|
|
|
|
@redisAction.getImageSize meetingID, presentationID, pageID, (err, width, height) =>
|
|
|
|
path = config.presentationImagePath(meetingID, presentationID, filename)
|
|
|
|
slides.push [path, width, height]
|
|
|
|
if slides.length is pageIDs.length
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
allSlidesEventObject = {
|
|
|
|
name : "all_slides",
|
|
|
|
meeting:{
|
|
|
|
id:meetingID,
|
|
|
|
sessionID:sessionID
|
|
|
|
},
|
|
|
|
slides: slides
|
|
|
|
}
|
|
|
|
@pub.publish receivers, JSON.stringify( allSlidesEventObject )
|
|
|
|
callback?(true)
|
|
|
|
|
2013-10-31 04:04:43 +08:00
|
|
|
# When the list of slides is loaded, we usually have to update the current image
|
|
|
|
# being show. This method can be use to do it.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishCurrentImagePath: (meetingID, sessionID, callback) ->
|
|
|
|
@redisAction.getPathToCurrentImage meetingID, (err, path) =>
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
@pub.publish receivers, JSON.stringify(["changeslide", path])
|
|
|
|
callback?(null, true)
|
|
|
|
|
|
|
|
# Publishes the current tool.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishTool: (meetingID, sessionID, callback) ->
|
|
|
|
@redisAction.getCurrentTool meetingID, (err, tool) =>
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
@pub.publish receivers, JSON.stringify(["toolChanged", tool])
|
|
|
|
callback?(null, true)
|
|
|
|
|
|
|
|
# Publishes a viewbox message.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishViewBox: (meetingID, sessionID, callback) ->
|
|
|
|
@redisAction.getCurrentPresentationID meetingID, (err, presentationID) =>
|
|
|
|
@redisAction.getViewBox meetingID, (err, viewBox) =>
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
@pub.publish receivers, JSON.stringify(["paper", viewBox[0], viewBox[1], viewBox[2], viewBox[3]])
|
|
|
|
callback?(null, true)
|
|
|
|
|
|
|
|
# Publishes a user leave message.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param pubID [string] the public ID of the user
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishUserLeave: (meetingID, sessionID, pubID, callback) ->
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
@pub.publish "bigbluebutton:bridge", JSON.stringify([receivers, "user leave", pubID])
|
|
|
|
callback?(null, true)
|
|
|
|
|
|
|
|
# Publishes a user list change to the appropriate clients.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
# @todo review if we really need this method
|
|
|
|
publishUsernames: (meetingID, sessionID, callback) ->
|
|
|
|
usernames = []
|
|
|
|
# @TODO: @_getUsers doesn't exist, probably this method is never being called
|
2013-10-31 05:32:03 +08:00
|
|
|
# @_getUsers meetingID, (users) =>
|
|
|
|
# users.forEach (user) =>
|
|
|
|
# usernames.push
|
|
|
|
# name: user.username
|
|
|
|
# id: user.pubID
|
|
|
|
|
|
|
|
# receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
# @pub.publish "bigbluebutton:bridge", JSON.stringify([receivers, "user list change", usernames])
|
|
|
|
callback?(null, true)
|
2013-10-31 04:04:43 +08:00
|
|
|
|
|
|
|
# Publishes a chat message informing that a text message is too long.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
|
|
|
# @param sessionID [string] the ID of the user, if `null` will send to all clients
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishChatMessageTooLong: (meetingID, sessionID, callback) ->
|
|
|
|
receivers = (if sessionID? then sessionID else meetingID)
|
|
|
|
@pub.publish receivers, JSON.stringify(["msg", "System", "Message too long."])
|
|
|
|
callback?(null, true)
|
|
|
|
|
|
|
|
# Publishes a chat message.
|
|
|
|
#
|
|
|
|
# @param meetingID [string] the ID of the meeting
|
2013-11-15 03:24:49 +08:00
|
|
|
# @param username [string] the username of the user that sent the message
|
|
|
|
# @param msg [string] the text message
|
|
|
|
# @param pubID [string] the public ID of the user sending the message
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishChatMessage2: (meetingID, username, msg, pubID, callback) ->
|
|
|
|
console.log("\n\n**publishChatMessage2: ")
|
|
|
|
chatMessageEventObj = {
|
|
|
|
name: "SendPublicChatMessage",
|
|
|
|
meeting:{
|
|
|
|
id: meetingID
|
|
|
|
},
|
|
|
|
chat: {
|
|
|
|
text: msg,
|
|
|
|
from: {
|
|
|
|
name: username
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@pub.publish "bigbluebutton:bridge", JSON.stringify(chatMessageEventObj)
|
|
|
|
callback?(null, true)
|
|
|
|
|
2013-10-31 04:04:43 +08:00
|
|
|
# Publishes a logout message to a user.
|
|
|
|
#
|
|
|
|
# @param sessionID [string] the ID of the user
|
|
|
|
# @param callback(err, succeeded) [Function] callback to call when finished
|
|
|
|
publishLogout: (sessionID, callback) ->
|
|
|
|
@pub.publish sessionID, JSON.stringify(["logout"])
|
|
|
|
callback?(null, true)
|