working on serializing message handling
This commit is contained in:
parent
db62de4e2f
commit
247349e9b4
@ -3,46 +3,46 @@
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
@addMeetingToCollection = (meetingId, name, intendedForRecording, voiceConf, duration, callback) ->
|
||||
#check if the meeting is already in the collection
|
||||
#check if the meeting is already in the collection
|
||||
|
||||
obj = Meteor.Meetings.upsert({meetingId:meetingId}, {$set: {
|
||||
meetingName:name
|
||||
intendedForRecording: intendedForRecording
|
||||
currentlyBeingRecorded: false # default value
|
||||
voiceConf: voiceConf
|
||||
duration: duration
|
||||
roomLockSettings:
|
||||
# by default the lock settings will be disabled on meeting create
|
||||
disablePrivateChat: false
|
||||
disableCam: false
|
||||
disableMic: false
|
||||
lockOnJoin: Meteor.config.lockOnJoin
|
||||
lockedLayout: false
|
||||
disablePublicChat: false
|
||||
lockOnJoinConfigurable: false # TODO
|
||||
}}, (err, numChanged) =>
|
||||
if numChanged.insertedId?
|
||||
funct = (cbk) ->
|
||||
Meteor.log.info "added MEETING #{meetingId}"
|
||||
cbk()
|
||||
funct(callback)
|
||||
else
|
||||
Meteor.log.error "nothing happened"
|
||||
callback()
|
||||
)
|
||||
obj = Meteor.Meetings.upsert({meetingId:meetingId}, {$set: {
|
||||
meetingName:name
|
||||
intendedForRecording: intendedForRecording
|
||||
currentlyBeingRecorded: false # default value
|
||||
voiceConf: voiceConf
|
||||
duration: duration
|
||||
roomLockSettings:
|
||||
# by default the lock settings will be disabled on meeting create
|
||||
disablePrivateChat: false
|
||||
disableCam: false
|
||||
disableMic: false
|
||||
lockOnJoin: Meteor.config.lockOnJoin
|
||||
lockedLayout: false
|
||||
disablePublicChat: false
|
||||
lockOnJoinConfigurable: false # TODO
|
||||
}}, (err, numChanged) =>
|
||||
if numChanged.insertedId?
|
||||
funct = (cbk) ->
|
||||
Meteor.log.info "added MEETING #{meetingId}"
|
||||
cbk()
|
||||
funct(callback)
|
||||
else
|
||||
Meteor.log.error "nothing happened"
|
||||
callback()
|
||||
)
|
||||
|
||||
|
||||
|
||||
@clearMeetingsCollection = (meetingId) ->
|
||||
if meetingId?
|
||||
Meteor.Meetings.remove({meetingId: meetingId},
|
||||
Meteor.log.info "cleared Meetings Collection (meetingId: #{meetingId}!")
|
||||
Meteor.log.info "cleared Meetings Collection (meetingId: #{meetingId}!")
|
||||
else
|
||||
Meteor.Meetings.remove({}, Meteor.log.info "cleared Meetings Collection (all meetings)!")
|
||||
|
||||
|
||||
#clean up upon a meeting's end
|
||||
@removeMeetingFromCollection = (meetingId) ->
|
||||
@removeMeetingFromCollection = (meetingId, callback) ->
|
||||
if Meteor.Meetings.findOne({meetingId: meetingId})?
|
||||
Meteor.log.info "end of meeting #{meetingId}. Clear the meeting data from all collections"
|
||||
# delete all users in the meeting
|
||||
@ -62,6 +62,16 @@
|
||||
|
||||
# delete the meeting
|
||||
clearMeetingsCollection(meetingId)
|
||||
|
||||
callback()
|
||||
else
|
||||
funct (localCallback) ->
|
||||
Meteor.log.error ("Error! There was no such meeting #{meetingId}")
|
||||
localCallback()
|
||||
funct(callback)
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# end Private methods on server
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
@ -139,7 +139,8 @@ Meteor.methods
|
||||
# Received information from BBB-Apps that a user left
|
||||
# Need to update the collection
|
||||
# params: meetingid, userid as defined in BBB-Apps
|
||||
@markUserOffline = (meetingId, userId) ->
|
||||
# callback
|
||||
@markUserOffline = (meetingId, userId, callback) ->
|
||||
# mark the user as offline. remove from the collection on meeting_end #TODO
|
||||
user = Meteor.Users.findOne({meetingId: meetingId, userId: userId})
|
||||
if user?.clientType is "HTML5"
|
||||
@ -153,16 +154,30 @@ Meteor.methods
|
||||
'user.listenOnly': false
|
||||
}}, (err, numChanged) ->
|
||||
if err?
|
||||
Meteor.log.error "_unsucc update (mark as offline) of user #{user?.user.name} #{userId} err=#{JSON.stringify err}"
|
||||
if numChanged?
|
||||
Meteor.log.info "_marking as offline html5 user #{user?.user.name} #{userId} numChanged=#{numChanged}"
|
||||
Meteor.log.error "_unsucc update (mark as offline) of user #{user?.user.name} #{userId}
|
||||
err=#{JSON.stringify err}"
|
||||
callback()
|
||||
else
|
||||
funct = (cbk) ->
|
||||
Meteor.log.info "_marking as offline html5 user #{user?.user.name}
|
||||
#{userId} numChanged=#{numChanged}"
|
||||
cbk()
|
||||
|
||||
funct(callback)
|
||||
)
|
||||
else
|
||||
Meteor.Users.remove({meetingId: meetingId, userId: userId}, (err, numDeletions) ->
|
||||
if err?
|
||||
Meteor.log.error "_unsucc deletion of user #{user?.user.name} #{userId} err=#{JSON.stringify err}"
|
||||
if numDeletions?
|
||||
Meteor.log.info "_deleting info for user #{user?.user.name} #{userId} numDeletions=#{numDeletions}"
|
||||
Meteor.log.error "_unsucc deletion of user #{user?.user.name} #{userId}
|
||||
err=#{JSON.stringify err}"
|
||||
callback()
|
||||
else
|
||||
funct = (cbk) ->
|
||||
Meteor.log.info "_deleting info for user #{user?.user.name} #{userId}
|
||||
numDeletions=#{numDeletions}"
|
||||
cbk()
|
||||
|
||||
funct(callback)
|
||||
)
|
||||
|
||||
|
||||
@ -293,7 +308,7 @@ Meteor.methods
|
||||
locked: user.voiceUser.locked
|
||||
muted: user.voiceUser.muted
|
||||
webcam_stream: user.webcam_stream
|
||||
}}, (err, numChanged) ->
|
||||
}}, (err) ->
|
||||
if err?
|
||||
Meteor.log.error "_error #{err} when trying to insert user #{userId}"
|
||||
callback()
|
||||
@ -326,7 +341,7 @@ Meteor.methods
|
||||
from_userid: 'SYSTEM_MESSAGE'
|
||||
from_username: ''
|
||||
from_time: user.timeOfJoining?.toString()
|
||||
}, (err, numChanged) ->
|
||||
}, (err) ->
|
||||
if err?
|
||||
Meteor.log.error "_error #{err} when trying to insert welcome message for #{userId}"
|
||||
else
|
||||
@ -383,7 +398,7 @@ Meteor.methods
|
||||
|
||||
@createDummyUser = (meetingId, userId, authToken) ->
|
||||
if Meteor.Users.findOne({userId:userId, meetingId: meetingId, authToken:authToken})?
|
||||
Meteor.log.info "html5 user userid:[#{userId}] from [#{meetingId}] tried to revalidate token"
|
||||
Meteor.log.info "html5 user userId:[#{userId}] from [#{meetingId}] tried to revalidate token"
|
||||
else
|
||||
Meteor.Users.insert({
|
||||
meetingId: meetingId
|
||||
@ -392,7 +407,7 @@ Meteor.methods
|
||||
clientType: "HTML5"
|
||||
validated: false #will be validated on validate_auth_token_reply
|
||||
}, (err, id) ->
|
||||
Meteor.log.info "_added a dummy html5 user with: userid=[#{userId}], id=[#{id}]
|
||||
Meteor.log.info "_added a dummy html5 user with: userId=[#{userId}]
|
||||
Users.size is now #{Meteor.Users.find({meetingId: meetingId}).count()}"
|
||||
)
|
||||
|
||||
|
@ -53,7 +53,7 @@ class Meteor.RedisPubSub
|
||||
_Q: (pattern, channel, jsonMsg) =>
|
||||
message = JSON.parse(jsonMsg)
|
||||
eventName = message.header.name
|
||||
console.log "Q " + eventName
|
||||
console.log "Q #{eventName} #{Meteor.myQueue.total()}"
|
||||
|
||||
|
||||
Meteor.myQueue.add({
|
||||
@ -61,7 +61,6 @@ class Meteor.RedisPubSub
|
||||
channel: channel
|
||||
jsonMsg: jsonMsg
|
||||
})
|
||||
Meteor.log.error Meteor.myQueue.total()
|
||||
|
||||
_onMessage: (pattern, channel, jsonMsg) =>
|
||||
# TODO: this has to be in a try/catch block, otherwise the server will
|
||||
@ -75,246 +74,6 @@ class Meteor.RedisPubSub
|
||||
Meteor.log.info "redis incoming message #{message.header.name} ",
|
||||
message: jsonMsg
|
||||
|
||||
if message.header.name is "get_users_reply" and message.payload.requester_id is "nodeJSapp"
|
||||
unless Meteor.Meetings.findOne({MeetingId: message.payload.meeting_id})?
|
||||
users = message.payload.users
|
||||
for user in users
|
||||
user.timeOfJoining = message.header.current_time # TODO this might need to be removed
|
||||
if user.emoji_status isnt 'none' and typeof user.emoji_status is 'string'
|
||||
user.set_emoji_time = new Date()
|
||||
userJoined meetingId, user
|
||||
return
|
||||
|
||||
if message.header.name is "validate_auth_token_reply"
|
||||
user = Meteor.Users.findOne({userId:message.payload.userid, meetingId: message.payload.meeting_id})
|
||||
validStatus = message.payload.valid
|
||||
|
||||
# if the user already exists in the db
|
||||
if user?.clientType is "HTML5"
|
||||
#if the html5 client user was validated successfully, add a flag
|
||||
Meteor.Users.update({userId:message.payload.userid, meetingId:message.payload.meeting_id}, {$set:{validated: validStatus}})
|
||||
Meteor.log.info "user.validated for user #{user.userId} in meeting #{user.meetingId} just
|
||||
became #{Meteor.Users.findOne({userId:message.payload.userid, meetingId: message.payload.meeting_id})?.validated}"
|
||||
else
|
||||
Meteor.log.info "a non-html5 user got validate_auth_token_reply."
|
||||
return
|
||||
|
||||
if message.header.name is "user_registered_message"
|
||||
#createDummyUser message.payload.meeting_id, message.payload.user
|
||||
return
|
||||
|
||||
if message.header.name is "user_left_message"
|
||||
userId = message.payload.user?.userid
|
||||
if userId? and meetingId?
|
||||
markUserOffline meetingId, userId
|
||||
return
|
||||
|
||||
if message.header.name is "disconnect_user_message"
|
||||
Meteor.log.info "a user(#{message.payload.userid}) was kicked out from meeting(#{message.payload.meeting_id})"
|
||||
return
|
||||
|
||||
if message.header.name is "get_chat_history_reply" and message.payload.requester_id is "nodeJSapp"
|
||||
unless Meteor.Meetings.findOne({MeetingId: message.payload.meeting_id})?
|
||||
for chatMessage in message.payload.chat_history
|
||||
addChatToCollection meetingId, chatMessage
|
||||
return
|
||||
|
||||
if message.header.name is "send_public_chat_message" or message.header.name is "send_private_chat_message"
|
||||
messageObject = message.payload.message
|
||||
# use current_time instead of message.from_time so that the chats from Flash and HTML5 have uniform times
|
||||
messageObject.from_time = message.header.current_time
|
||||
addChatToCollection meetingId, messageObject
|
||||
return
|
||||
|
||||
if message.header.name is "presentation_shared_message"
|
||||
presentationId = message.payload.presentation?.id
|
||||
# change the currently displayed presentation to presentation.current = false
|
||||
Meteor.Presentations.update({"presentation.current": true, meetingId: meetingId},{$set: {"presentation.current": false}})
|
||||
|
||||
#update(if already present) entirely the presentation with the fresh data
|
||||
removePresentationFromCollection meetingId, presentationId
|
||||
addPresentationToCollection meetingId, message.payload.presentation
|
||||
|
||||
for slide in message.payload.presentation?.pages
|
||||
addSlideToCollection meetingId, message.payload.presentation?.id, slide
|
||||
if slide.current
|
||||
displayThisSlide meetingId, slide.id, slide
|
||||
return
|
||||
|
||||
if message.header.name is "get_presentation_info_reply" and message.payload.requester_id is "nodeJSapp"
|
||||
for presentation in message.payload.presentations
|
||||
addPresentationToCollection meetingId, presentation
|
||||
|
||||
for page in presentation.pages
|
||||
#add the slide to the collection
|
||||
addSlideToCollection meetingId, presentation.id, page
|
||||
|
||||
#request for shapes
|
||||
whiteboardId = "#{presentation.id}/#{page.num}" # d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f-1404411622872/1
|
||||
#Meteor.log.info "the whiteboard_id here is:" + whiteboardId
|
||||
|
||||
message =
|
||||
"payload":
|
||||
"meeting_id": meetingId
|
||||
"requester_id": "nodeJSapp"
|
||||
"whiteboard_id": whiteboardId
|
||||
"header":
|
||||
"timestamp": new Date().getTime()
|
||||
"name": "get_whiteboard_shapes_request"
|
||||
"version": "0.0.1"
|
||||
|
||||
if whiteboardId? and meetingId?
|
||||
publish Meteor.config.redis.channels.toBBBApps.whiteboard, message #TODO
|
||||
else
|
||||
Meteor.log.info "did not have enough information to send a user_leaving_request" #TODO
|
||||
return
|
||||
|
||||
if message.header.name is "presentation_page_changed_message"
|
||||
newSlide = message.payload.page
|
||||
displayThisSlide meetingId, newSlide?.id, newSlide
|
||||
return
|
||||
|
||||
if message.header.name is "get_whiteboard_shapes_reply" and message.payload.requester_id is "nodeJSapp"
|
||||
|
||||
# Create a whiteboard clean status or find one for the current meeting
|
||||
if not Meteor.WhiteboardCleanStatus.findOne({meetingId: meetingId})?
|
||||
Meteor.WhiteboardCleanStatus.insert({meetingId: meetingId, in_progress: false})
|
||||
|
||||
for shape in message.payload.shapes
|
||||
whiteboardId = shape.wb_id
|
||||
addShapeToCollection meetingId, whiteboardId, shape
|
||||
return
|
||||
|
||||
if message.header.name is "send_whiteboard_shape_message"
|
||||
|
||||
#Meteor stringifies an array of JSONs (...shape.result) in this message
|
||||
#parsing the String and reassigning the value
|
||||
if message.payload.shape.shape_type is "poll_result" and typeof message.payload.shape.shape.result is 'string'
|
||||
message.payload.shape.shape.result = JSON.parse message.payload.shape.shape.result
|
||||
|
||||
shape = message.payload.shape
|
||||
whiteboardId = shape?.wb_id
|
||||
addShapeToCollection meetingId, whiteboardId, shape
|
||||
return
|
||||
|
||||
if message.header.name is "presentation_cursor_updated_message"
|
||||
x = message.payload.x_percent
|
||||
y = message.payload.y_percent
|
||||
Meteor.Presentations.update({"presentation.current": true, meetingId: meetingId},{$set: {"pointer.x": x, "pointer.y": y}})
|
||||
return
|
||||
|
||||
if message.header.name is "whiteboard_cleared_message"
|
||||
whiteboardId = message.payload.whiteboard_id
|
||||
Meteor.WhiteboardCleanStatus.update({meetingId: meetingId}, {$set: {'in_progress': true}})
|
||||
removeAllShapesFromSlide meetingId, whiteboardId
|
||||
return
|
||||
|
||||
if message.header.name is "undo_whiteboard_request"
|
||||
whiteboardId = message.payload.whiteboard_id
|
||||
shapeId = message.payload.shape_id
|
||||
removeShapeFromSlide meetingId, whiteboardId, shapeId
|
||||
return
|
||||
|
||||
if message.header.name is "presenter_assigned_message"
|
||||
newPresenterId = message.payload.new_presenter_id
|
||||
if newPresenterId?
|
||||
# reset the previous presenter
|
||||
Meteor.Users.update({"user.presenter": true, meetingId: meetingId},{$set: {"user.presenter": false}})
|
||||
# set the new presenter
|
||||
Meteor.Users.update({"user.userid": newPresenterId, meetingId: meetingId},{$set: {"user.presenter": true}})
|
||||
return
|
||||
|
||||
if message.header.name is "presentation_page_resized_message"
|
||||
slideId = message.payload.page?.id
|
||||
heightRatio = message.payload.page?.height_ratio
|
||||
widthRatio = message.payload.page?.width_ratio
|
||||
xOffset = message.payload.page?.x_offset
|
||||
yOffset = message.payload.page?.y_offset
|
||||
presentationId = slideId.split("/")[0]
|
||||
Meteor.Slides.update({presentationId: presentationId, "slide.current": true}, {$set: {"slide.height_ratio": heightRatio, "slide.width_ratio": widthRatio, "slide.x_offset": xOffset, "slide.y_offset": yOffset}})
|
||||
return
|
||||
|
||||
if message.header.name is "user_emoji_status_message"
|
||||
userId = message.payload.userid
|
||||
meetingId = message.payload.meeting_id
|
||||
emojiStatus = message.payload.emoji_status
|
||||
if userId? and meetingId?
|
||||
set_emoji_time = new Date()
|
||||
Meteor.Users.update({"user.userid": userId},{$set: {"user.set_emoji_time": set_emoji_time, "user.emoji_status": emojiStatus}})
|
||||
return
|
||||
|
||||
if message.header.name is "recording_status_changed_message"
|
||||
intendedForRecording = message.payload.recorded
|
||||
currentlyBeingRecorded = message.payload.recording
|
||||
Meteor.Meetings.update({meetingId: meetingId, intendedForRecording: intendedForRecording}, {$set: {currentlyBeingRecorded: currentlyBeingRecorded}})
|
||||
return
|
||||
|
||||
# --------------------------------------------------
|
||||
# lock settings ------------------------------------
|
||||
if message.header.name is "eject_voice_user_message"
|
||||
return
|
||||
|
||||
if message.header.name is "new_permission_settings"
|
||||
oldSettings = Meteor.Meetings.findOne({meetingId:meetingId})?.roomLockSettings
|
||||
newSettings = message.payload?.permissions
|
||||
|
||||
# if the disableMic setting was turned on
|
||||
if !oldSettings?.disableMic and newSettings.disableMic
|
||||
handleLockingMic(meetingId, newSettings)
|
||||
|
||||
# substitute with the new lock settings
|
||||
Meteor.Meetings.update({meetingId: meetingId}, {$set: {
|
||||
'roomLockSettings.disablePrivateChat': newSettings.disablePrivateChat
|
||||
'roomLockSettings.disableCam': newSettings.disableCam
|
||||
'roomLockSettings.disableMic': newSettings.disableMic
|
||||
'roomLockSettings.lockOnJoin': newSettings.lockOnJoin
|
||||
'roomLockSettings.lockedLayout': newSettings.lockedLayout
|
||||
'roomLockSettings.disablePublicChat': newSettings.disablePublicChat
|
||||
'roomLockSettings.lockOnJoinConfigurable': newSettings.lockOnJoinConfigurable #TODO
|
||||
}})
|
||||
return
|
||||
|
||||
if message.header.name is "user_locked_message" or message.header.name is "user_unlocked_message"
|
||||
userId = message.payload.userid
|
||||
isLocked = message.payload.locked
|
||||
setUserLockedStatus(meetingId, userId, isLocked)
|
||||
return
|
||||
|
||||
if message.header.name in ["meeting_ended_message", "meeting_destroyed_event",
|
||||
"end_and_kick_all_message", "disconnect_all_users_message"]
|
||||
if Meteor.Meetings.findOne({meetingId: meetingId})?
|
||||
Meteor.log.info "there are #{Meteor.Users.find({meetingId: meetingId}).count()} users in the meeting"
|
||||
for user in Meteor.Users.find({meetingId: meetingId}).fetch()
|
||||
markUserOffline meetingId, user.userId
|
||||
#TODO should we clear the chat messages for that meeting?!
|
||||
unless message.header.name is "disconnect_all_users_message"
|
||||
removeMeetingFromCollection meetingId
|
||||
return
|
||||
|
||||
if message.header.name is "poll_started_message"
|
||||
if message.payload.meeting_id? and message.payload.requester_id? and message.payload.poll?
|
||||
if Meteor.Meetings.findOne({meetingId: message.payload.meeting_id})?
|
||||
#initializing the list of current users
|
||||
users = Meteor.Users.find({meetingId: message.payload.meeting_id}, {fields:{"user.userid": 1, _id: 0}} ).fetch()
|
||||
addPollToCollection message.payload.poll, message.payload.requester_id, users, message.payload.meeting_id
|
||||
|
||||
if message.header.name is "poll_stopped_message"
|
||||
meetingId = message.payload.meeting_id
|
||||
poll_id = message.payload.poll_id
|
||||
clearPollCollection meetingId, poll_id
|
||||
|
||||
if message.header.name is "user_voted_poll_message"
|
||||
if message.payload?.poll? and message.payload.meeting_id? and message.payload.presenter_id?
|
||||
pollObj = message.payload.poll
|
||||
meetingId = message.payload.meeting_id
|
||||
requesterId = message.payload.presenter_id
|
||||
updatePollCollection pollObj, meetingId, requesterId
|
||||
|
||||
if message.header.name is "poll_show_result_message"
|
||||
if message.payload.poll.id? and message.payload.meeting_id?
|
||||
poll_id = message.payload.poll.id
|
||||
meetingId = message.payload.meeting_id
|
||||
clearPollCollection meetingId, poll_id
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# Private methods on server
|
||||
|
@ -41,7 +41,7 @@ Meteor.startup ->
|
||||
# for the same user.
|
||||
@handleRedisMessage = (data, callback) ->
|
||||
message = JSON.parse(data.jsonMsg)
|
||||
correlationId = message.payload?.reply_to or message.header?.reply_to
|
||||
# correlationId = message.payload?.reply_to or message.header?.reply_to
|
||||
meetingId = message.payload?.meeting_id
|
||||
|
||||
# Avoid cluttering the log with json messages carrying little or repetitive
|
||||
@ -91,19 +91,22 @@ Meteor.startup ->
|
||||
'user_voice_talking_message'
|
||||
'user_voice_muted_message']
|
||||
|
||||
updateVoiceUser meetingId, callback,
|
||||
voiceUserObj = {
|
||||
'web_userid': message.payload.user.voiceUser.web_userid
|
||||
'listen_only': message.payload.listen_only
|
||||
'talking': message.payload.user.voiceUser.talking
|
||||
'joined': message.payload.user.voiceUser.joined
|
||||
'locked': message.payload.user.voiceUser.locked
|
||||
'muted': message.payload.user.voiceUser.muted
|
||||
}
|
||||
updateVoiceUser meetingId, voiceUserObj, callback
|
||||
|
||||
else if eventName is 'user_listening_only'
|
||||
updateVoiceUser meetingId,
|
||||
{'web_userid': message.payload.userid
|
||||
'listen_only': message.payload.listen_only},
|
||||
callback
|
||||
voiceUserObj = {
|
||||
'web_userid': message.payload.userid
|
||||
'listen_only': message.payload.listen_only
|
||||
}
|
||||
updateVoiceUser meetingId, voiceUserObj, callback
|
||||
|
||||
else if eventName is 'get_all_meetings_reply'
|
||||
Meteor.log.info "Let's store some data for the running meetings
|
||||
@ -111,6 +114,8 @@ Meteor.startup ->
|
||||
Meteor.log.info JSON.stringify(message)
|
||||
listOfMeetings = message.payload.meetings
|
||||
|
||||
# Processing the meetings recursively with a callback to notify us,
|
||||
# ensuring that we update the meeting collection serially
|
||||
processMeeting = () ->
|
||||
meeting = listOfMeetings.pop()
|
||||
if meeting?
|
||||
@ -122,9 +127,9 @@ Meteor.startup ->
|
||||
processMeeting()
|
||||
|
||||
else if eventName is 'user_joined_message'
|
||||
Meteor.log.error JSON.stringify message
|
||||
userObj = message.payload.user
|
||||
dbUser = Meteor.Users.findOne({userId: message.payload.user.userid
|
||||
meetingId: message.payload.meeting_id})
|
||||
dbUser = Meteor.Users.findOne({userId: userObj.userid, meetingId: message.payload.meeting_id})
|
||||
|
||||
# On attempting reconnection of Flash clients (in voiceBridge) we receive
|
||||
# an extra user_joined_message. Ignore it as it will add an extra user
|
||||
@ -140,8 +145,80 @@ Meteor.startup ->
|
||||
Meteor.log.info "in user_joined_message the validStatus
|
||||
of the user was #{status}"
|
||||
userObj.timeOfJoining = message.header.current_time
|
||||
userJoined meetingId, userObj, callback
|
||||
# return
|
||||
userJoined meetingId, userObj, callback
|
||||
else
|
||||
callback()
|
||||
|
||||
|
||||
|
||||
# only process if requester is nodeJSapp means only process in the case when
|
||||
# we explicitly request the users
|
||||
else if eventName is 'get_users_reply' and message.payload.requester_id is 'nodeJSapp'
|
||||
|
||||
Meteor.log.error JSON.stringify(message)
|
||||
if !Meteor.Meetings.findOne({meetingId: meetingId})? #TODO consider removing this cond
|
||||
users = message.payload.users
|
||||
|
||||
#TODO make the serialization be split per meeting. This will allow us to
|
||||
# use N threads vs 1 and we'll take advantage of Mongo's concurrency tricks
|
||||
|
||||
# Processing the users recursively with a callback to notify us,
|
||||
# ensuring that we update the users collection serially
|
||||
processUser = () ->
|
||||
console.log "1"
|
||||
user = users.pop()
|
||||
if user?
|
||||
console.log "2"
|
||||
user.timeOfJoining = message.header.current_time
|
||||
if user.emoji_status isnt 'none' and typeof user.emoji_status is 'string'
|
||||
console.log "3"
|
||||
user.set_emoji_time = new Date()
|
||||
userJoined meetingId, user, processUser
|
||||
else
|
||||
console.error("this is not supposed to happen")
|
||||
userJoined meetingId, user, processUser
|
||||
else
|
||||
console.log "4"
|
||||
callback() # all meeting arrays (if any) have been processed
|
||||
|
||||
processUser()
|
||||
else
|
||||
callback() #TODO test if we get here
|
||||
|
||||
|
||||
else if eventName is 'validate_auth_token_reply'
|
||||
userId = message.payload.userid
|
||||
user = Meteor.Users.findOne({userId:userId, meetingId: meetingId})
|
||||
validStatus = message.payload.valid
|
||||
|
||||
# if the user already exists in the db
|
||||
if user?.clientType is "HTML5"
|
||||
#if the html5 client user was validated successfully, add a flag
|
||||
Meteor.Users.update({userId:userId, meetingId:message.payload.meeting_id},
|
||||
{$set:{validated: validStatus}},
|
||||
(err, numChanged) ->
|
||||
if numChanged.insertedId?
|
||||
funct = (cbk) ->
|
||||
val=Meteor.Users.findOne({userId:userId, meetingId: message.payload.meeting_id})?.validated
|
||||
Meteor.log.info "user.validated for user #{userId} in meeting #{user.meetingId} just became #{val}"
|
||||
cbk()
|
||||
|
||||
funct(callback)
|
||||
else
|
||||
callback()
|
||||
)
|
||||
else
|
||||
Meteor.log.info "a non-html5 user got validate_auth_token_reply."
|
||||
callback()
|
||||
|
||||
|
||||
|
||||
else if eventName is 'user_left_message'
|
||||
userId = message.payload.user?.userid
|
||||
if userId? and meetingId?
|
||||
markUserOffline meetingId, userId, callback
|
||||
else
|
||||
callback() #TODO check how to get these cases out and reuse code
|
||||
|
||||
|
||||
|
||||
@ -149,8 +226,271 @@ Meteor.startup ->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is 'presenter_assigned_message'
|
||||
newPresenterId = message.payload.new_presenter_id
|
||||
if newPresenterId?
|
||||
# reset the previous presenter
|
||||
Meteor.Users.update({"user.presenter": true, meetingId: meetingId},
|
||||
{$set: {"user.presenter": false}},
|
||||
(err, numUpdated) ->
|
||||
Meteor.log.info(" Updating old presenter numUpdated=#{numUpdated},
|
||||
err=#{err}")
|
||||
)
|
||||
# set the new presenter
|
||||
Meteor.Users.update({"user.userid": newPresenterId, meetingId: meetingId},
|
||||
{$set: {"user.presenter": true}},
|
||||
(err, numUpdated) ->
|
||||
Meteor.log.info(" Updating new presenter numUpdated=#{numUpdated},
|
||||
err=#{err}")
|
||||
)
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is 'user_emoji_status_message'
|
||||
userId = message.payload.userid
|
||||
meetingId = message.payload.meeting_id
|
||||
emojiStatus = message.payload.emoji_status
|
||||
if userId? and meetingId?
|
||||
set_emoji_time = new Date()
|
||||
Meteor.Users.update({"user.userid": userId},
|
||||
{$set:{"user.set_emoji_time":set_emoji_time,"user.emoji_status":emojiStatus}},
|
||||
(err, numUpdated) ->
|
||||
Meteor.log.info(" Updating emoji numUpdated=#{numUpdated}, err=#{err}")
|
||||
)
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName in ['user_locked_message', 'user_unlocked_message']
|
||||
userId = message.payload.userid
|
||||
isLocked = message.payload.locked
|
||||
setUserLockedStatus(meetingId, userId, isLocked)
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName in ["meeting_ended_message", "meeting_destroyed_event",
|
||||
"end_and_kick_all_message", "disconnect_all_users_message"]
|
||||
Meteor.log.info("DESTROYING MEETING #{meetingId}")
|
||||
removeMeetingFromCollection meetingId, callback
|
||||
|
||||
###
|
||||
if Meteor.Meetings.findOne({meetingId: meetingId})?
|
||||
count=Meteor.Users.find({meetingId: meetingId}).count()
|
||||
Meteor.log.info "there are #{count} users in the meeting"
|
||||
for user in Meteor.Users.find({meetingId: meetingId}).fetch()
|
||||
markUserOffline meetingId, user.userId
|
||||
#TODO should we clear the chat messages for that meeting?!
|
||||
unless eventName is "disconnect_all_users_message"
|
||||
removeMeetingFromCollection meetingId
|
||||
###
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "get_chat_history_reply" and message.payload.requester_id is "nodeJSapp"
|
||||
unless Meteor.Meetings.findOne({MeetingId: message.payload.meeting_id})?
|
||||
for chatMessage in message.payload.chat_history
|
||||
addChatToCollection meetingId, chatMessage
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "send_public_chat_message" or eventName is "send_private_chat_message"
|
||||
messageObject = message.payload.message
|
||||
# use current_time instead of message.from_time so that the chats from Flash and HTML5 have uniform times
|
||||
messageObject.from_time = message.header.current_time
|
||||
addChatToCollection meetingId, messageObject
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "presentation_shared_message"
|
||||
presentationId = message.payload.presentation?.id
|
||||
# change the currently displayed presentation to presentation.current = false
|
||||
Meteor.Presentations.update({"presentation.current": true, meetingId: meetingId},{$set: {"presentation.current": false}})
|
||||
|
||||
#update(if already present) entirely the presentation with the fresh data
|
||||
removePresentationFromCollection meetingId, presentationId
|
||||
addPresentationToCollection meetingId, message.payload.presentation
|
||||
|
||||
for slide in message.payload.presentation?.pages
|
||||
addSlideToCollection meetingId, message.payload.presentation?.id, slide
|
||||
if slide.current
|
||||
displayThisSlide meetingId, slide.id, slide
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "get_presentation_info_reply" and message.payload.requester_id is "nodeJSapp"
|
||||
for presentation in message.payload.presentations
|
||||
addPresentationToCollection meetingId, presentation
|
||||
|
||||
for page in presentation.pages
|
||||
#add the slide to the collection
|
||||
addSlideToCollection meetingId, presentation.id, page
|
||||
|
||||
#request for shapes
|
||||
whiteboardId = "#{presentation.id}/#{page.num}" # d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f-1404411622872/1
|
||||
#Meteor.log.info "the whiteboard_id here is:" + whiteboardId
|
||||
|
||||
message =
|
||||
"payload":
|
||||
"meeting_id": meetingId
|
||||
"requester_id": "nodeJSapp"
|
||||
"whiteboard_id": whiteboardId
|
||||
"header":
|
||||
"timestamp": new Date().getTime()
|
||||
"name": "get_whiteboard_shapes_request"
|
||||
"version": "0.0.1"
|
||||
|
||||
if whiteboardId? and meetingId?
|
||||
publish Meteor.config.redis.channels.toBBBApps.whiteboard, message #TODO
|
||||
else
|
||||
Meteor.log.info "did not have enough information to send a user_leaving_request" #TODO
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "presentation_page_changed_message"
|
||||
newSlide = message.payload.page
|
||||
displayThisSlide meetingId, newSlide?.id, newSlide
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "get_whiteboard_shapes_reply" and message.payload.requester_id is "nodeJSapp"
|
||||
# Create a whiteboard clean status or find one for the current meeting
|
||||
if not Meteor.WhiteboardCleanStatus.findOne({meetingId: meetingId})?
|
||||
Meteor.WhiteboardCleanStatus.insert({meetingId: meetingId, in_progress: false})
|
||||
|
||||
for shape in message.payload.shapes
|
||||
whiteboardId = shape.wb_id
|
||||
addShapeToCollection meetingId, whiteboardId, shape
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "send_whiteboard_shape_message"
|
||||
#Meteor stringifies an array of JSONs (...shape.result) in this message
|
||||
#parsing the String and reassigning the value
|
||||
if message.payload.shape.shape_type is "poll_result" and typeof message.payload.shape.shape.result is 'string'
|
||||
message.payload.shape.shape.result = JSON.parse message.payload.shape.shape.result
|
||||
|
||||
shape = message.payload.shape
|
||||
whiteboardId = shape?.wb_id
|
||||
addShapeToCollection meetingId, whiteboardId, shape
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "presentation_cursor_updated_message"
|
||||
x = message.payload.x_percent
|
||||
y = message.payload.y_percent
|
||||
Meteor.Presentations.update({"presentation.current": true, meetingId: meetingId},
|
||||
{$set: {"pointer.x": x, "pointer.y": y}})
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "whiteboard_cleared_message"
|
||||
whiteboardId = message.payload.whiteboard_id
|
||||
Meteor.WhiteboardCleanStatus.update({meetingId: meetingId}, {$set: {'in_progress': true}})
|
||||
removeAllShapesFromSlide meetingId, whiteboardId
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "undo_whiteboard_request"
|
||||
whiteboardId = message.payload.whiteboard_id
|
||||
shapeId = message.payload.shape_id
|
||||
removeShapeFromSlide meetingId, whiteboardId, shapeId
|
||||
callback()
|
||||
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "presentation_page_resized_message"
|
||||
slideId = message.payload.page?.id
|
||||
heightRatio = message.payload.page?.height_ratio
|
||||
widthRatio = message.payload.page?.width_ratio
|
||||
xOffset = message.payload.page?.x_offset
|
||||
yOffset = message.payload.page?.y_offset
|
||||
presentationId = slideId.split("/")[0]
|
||||
Meteor.Slides.update({presentationId: presentationId, "slide.current": true},
|
||||
{$set: {"slide.height_ratio": heightRatio
|
||||
"slide.width_ratio": widthRatio
|
||||
"slide.x_offset": xOffset
|
||||
"slide.y_offset": yOffset}}
|
||||
)
|
||||
callback()
|
||||
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "recording_status_changed_message"
|
||||
intendedForRecording = message.payload.recorded
|
||||
currentlyBeingRecorded = message.payload.recording
|
||||
Meteor.Meetings.update({meetingId: meetingId, intendedForRecording: intendedForRecording},
|
||||
{$set: {currentlyBeingRecorded: currentlyBeingRecorded}}
|
||||
)
|
||||
callback()
|
||||
|
||||
# --------------------------------------------------
|
||||
# lock settings ------------------------------------
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "eject_voice_user_message"
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "new_permission_settings"
|
||||
oldSettings = Meteor.Meetings.findOne({meetingId:meetingId})?.roomLockSettings
|
||||
newSettings = message.payload?.permissions
|
||||
|
||||
# if the disableMic setting was turned on
|
||||
if !oldSettings?.disableMic and newSettings.disableMic
|
||||
handleLockingMic(meetingId, newSettings)
|
||||
|
||||
# substitute with the new lock settings
|
||||
Meteor.Meetings.update({meetingId: meetingId}, {$set: {
|
||||
'roomLockSettings.disablePrivateChat': newSettings.disablePrivateChat
|
||||
'roomLockSettings.disableCam': newSettings.disableCam
|
||||
'roomLockSettings.disableMic': newSettings.disableMic
|
||||
'roomLockSettings.lockOnJoin': newSettings.lockOnJoin
|
||||
'roomLockSettings.lockedLayout': newSettings.lockedLayout
|
||||
'roomLockSettings.disablePublicChat': newSettings.disablePublicChat
|
||||
'roomLockSettings.lockOnJoinConfigurable': newSettings.lockOnJoinConfigurable #TODO
|
||||
}})
|
||||
callback()
|
||||
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "poll_started_message"
|
||||
if message.payload.meeting_id? and message.payload.requester_id? and message.payload.poll?
|
||||
if Meteor.Meetings.findOne({meetingId: message.payload.meeting_id})?
|
||||
#initializing the list of current users
|
||||
users = Meteor.Users.find({meetingId: message.payload.meeting_id},
|
||||
{fields:{"user.userid": 1, _id: 0}} ).fetch()
|
||||
addPollToCollection message.payload.poll, message.payload.requester_id,
|
||||
users, message.payload.meeting_id
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "poll_stopped_message"
|
||||
meetingId = message.payload.meeting_id
|
||||
poll_id = message.payload.poll_id
|
||||
clearPollCollection meetingId, poll_id
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "user_voted_poll_message"
|
||||
if message.payload?.poll? and message.payload.meeting_id? and message.payload.presenter_id?
|
||||
pollObj = message.payload.poll
|
||||
meetingId = message.payload.meeting_id
|
||||
requesterId = message.payload.presenter_id
|
||||
updatePollCollection pollObj, meetingId, requesterId
|
||||
callback()
|
||||
|
||||
# for now not handling this serially #TODO
|
||||
else if eventName is "poll_show_result_message"
|
||||
if message.payload.poll.id? and message.payload.meeting_id?
|
||||
poll_id = message.payload.poll.id
|
||||
meetingId = message.payload.meeting_id
|
||||
clearPollCollection meetingId, poll_id
|
||||
callback()
|
||||
|
||||
|
||||
else # keep moving in the queue
|
||||
Meteor.log.info "WARNING!!!\n
|
||||
THE JSON MESSAGE WAS NOT OF TYPE SUPPORTED BY THIS APPLICATION\n
|
||||
#{eventName} {JSON.stringify message}"
|
||||
unless eventName in notLoggedEventTypes
|
||||
Meteor.log.info "WARNING!!!\n
|
||||
THE JSON MESSAGE WAS NOT OF TYPE SUPPORTED BY THIS APPLICATION\n
|
||||
#{eventName} {JSON.stringify message}"
|
||||
callback()
|
||||
|
Loading…
Reference in New Issue
Block a user