2014-04-14 07:39:18 +08:00
|
|
|
redis = require 'redis'
|
|
|
|
crypto = require 'crypto'
|
|
|
|
postal = require 'postal'
|
|
|
|
|
2014-04-24 05:37:19 +08:00
|
|
|
config = require '../config'
|
2014-04-24 04:18:25 +08:00
|
|
|
log = require './bbblogger'
|
|
|
|
|
|
|
|
module.exports = class RedisPubSub
|
|
|
|
|
|
|
|
constructor: ->
|
|
|
|
@pubClient = redis.createClient()
|
|
|
|
@subClient = redis.createClient()
|
|
|
|
|
|
|
|
# hash to store requests waiting for response
|
|
|
|
@pendingRequests = {}
|
2014-04-14 07:39:18 +08:00
|
|
|
|
2014-04-24 04:18:25 +08:00
|
|
|
postal.subscribe
|
2014-04-24 05:37:19 +08:00
|
|
|
channel: config.redis.internalChannels.publish
|
2014-04-24 04:18:25 +08:00
|
|
|
topic: 'broadcast'
|
2014-04-25 05:33:59 +08:00
|
|
|
callback: (msg, envelope) =>
|
2014-04-24 04:18:25 +08:00
|
|
|
if envelope.replyTo?
|
2014-04-25 05:33:59 +08:00
|
|
|
@sendAndWaitForReply(msg, envelope)
|
2014-04-24 04:18:25 +08:00
|
|
|
else
|
2014-04-25 05:33:59 +08:00
|
|
|
@send(msg, envelope)
|
|
|
|
|
2014-05-09 05:32:09 +08:00
|
|
|
@subClient.on "psubscribe", @_onSubscribe
|
|
|
|
@subClient.on "pmessage", @_onMessage
|
2014-04-25 05:33:59 +08:00
|
|
|
|
|
|
|
log.info("RPC: Subscribing message on channel: #{config.redis.channels.fromBBBApps}")
|
2014-05-09 05:32:09 +08:00
|
|
|
@subClient.psubscribe(config.redis.channels.fromBBBApps)
|
2014-04-24 04:18:25 +08:00
|
|
|
|
2014-04-25 05:33:59 +08:00
|
|
|
# Sends a message and waits for a reply
|
2014-04-24 04:18:25 +08:00
|
|
|
sendAndWaitForReply: (message, envelope) ->
|
|
|
|
# generate a unique correlation id for this call
|
|
|
|
correlationId = crypto.randomBytes(16).toString('hex')
|
|
|
|
|
|
|
|
# create a timeout for what should happen if we don't get a response
|
|
|
|
timeoutId = setTimeout( (correlationId) =>
|
|
|
|
response = {}
|
|
|
|
# if this ever gets called we didn't get a response in a timely fashion
|
|
|
|
response.err =
|
|
|
|
code: "503"
|
|
|
|
message: "Waiting for reply timeout."
|
|
|
|
description: "Waiting for reply timeout."
|
|
|
|
postal.publish
|
|
|
|
channel: envelope.replyTo.channel
|
|
|
|
topic: envelope.replyTo.topic
|
|
|
|
data: response
|
|
|
|
# delete the entry from hash
|
|
|
|
delete @pendingRequests[correlationId]
|
2014-04-25 05:33:59 +08:00
|
|
|
, config.redis.timeout, correlationId)
|
2014-04-24 04:18:25 +08:00
|
|
|
|
|
|
|
# create a request entry to store in a hash
|
|
|
|
entry =
|
|
|
|
replyTo: envelope.replyTo
|
|
|
|
timeout: timeoutId #the id for the timeout so we can clear it
|
|
|
|
|
|
|
|
# put the entry in the hash so we can match the response later
|
|
|
|
@pendingRequests[correlationId] = entry
|
2014-05-16 04:42:54 +08:00
|
|
|
message.header.reply_to = correlationId
|
2014-05-30 23:57:18 +08:00
|
|
|
console.log "\n Waiting for a reply on:" + JSON.stringify(message)
|
2014-05-16 04:42:54 +08:00
|
|
|
log.info({ message: message, channel: config.redis.channels.toBBBApps.meeting}, "Publishing a message")
|
|
|
|
@pubClient.publish(config.redis.channels.toBBBApps.meeting, JSON.stringify(message))
|
2014-04-14 07:39:18 +08:00
|
|
|
|
2014-04-25 05:33:59 +08:00
|
|
|
# Send a message without waiting for a reply
|
|
|
|
send: (message, envelope) ->
|
|
|
|
# TODO
|
|
|
|
|
|
|
|
_onSubscribe: (channel, count) =>
|
|
|
|
log.info("Subscribed to #{channel}")
|
|
|
|
|
2014-05-09 05:32:09 +08:00
|
|
|
_onMessage: (pattern, channel, jsonMsg) =>
|
2014-04-25 05:33:59 +08:00
|
|
|
# TODO: this has to be in a try/catch block, otherwise the server will
|
|
|
|
# crash if the message has a bad format
|
|
|
|
message = JSON.parse(jsonMsg)
|
2014-05-30 23:57:18 +08:00
|
|
|
correlationId = message.payload?.reply_to or message.header?.reply_to
|
2014-05-23 03:25:00 +08:00
|
|
|
|
2014-05-30 23:57:18 +08:00
|
|
|
unless message.header?.name is "keep_alive_reply"
|
|
|
|
console.log "\nchannel=" + channel
|
|
|
|
console.log "correlationId=" + correlationId if correlationId?
|
|
|
|
console.log "eventType=" + message.header?.name + "\n"
|
|
|
|
log.debug({ pattern: pattern, channel: channel, message: message}, "Received a message from redis")
|
2014-04-25 05:33:59 +08:00
|
|
|
|
|
|
|
# retrieve the request entry
|
2014-05-21 02:54:20 +08:00
|
|
|
|
2014-04-25 05:33:59 +08:00
|
|
|
if correlationId? and @pendingRequests?[correlationId]?
|
|
|
|
entry = @pendingRequests[correlationId]
|
|
|
|
# make sure the message in the timeout isn't triggered by clearing it
|
|
|
|
clearTimeout(entry.timeout)
|
|
|
|
|
|
|
|
delete @pendingRequests[correlationId]
|
|
|
|
postal.publish
|
|
|
|
channel: entry.replyTo.channel
|
|
|
|
topic: entry.replyTo.topic
|
|
|
|
data: message
|
|
|
|
else
|
2014-05-31 00:32:00 +08:00
|
|
|
if message.header?.name is 'get_presentation_info_reply'
|
|
|
|
#filter for the current=true page on the server-side
|
|
|
|
currentPage = null
|
2014-06-04 23:14:23 +08:00
|
|
|
numCurrentPage = null
|
2014-05-31 00:32:00 +08:00
|
|
|
presentations = message.payload?.presentations
|
|
|
|
|
|
|
|
for presentation in presentations
|
|
|
|
pages = presentation.pages
|
|
|
|
|
|
|
|
for page in pages
|
|
|
|
if page.current is true
|
|
|
|
currentPage = page
|
2014-06-04 23:14:23 +08:00
|
|
|
numCurrentPage = page.num
|
|
|
|
|
|
|
|
console.log "\n\n\n\n the message is: " + JSON.stringify message
|
|
|
|
console.log "\n" + message.payload?.presentations[0]?.id + "/" + numCurrentPage + "\n\n"
|
|
|
|
#request the whiteboard information
|
|
|
|
requestMessage = {
|
|
|
|
"payload": {
|
|
|
|
"meeting_id": message.payload?.meeting_id
|
|
|
|
"requester_id": message.payload?.requester_id
|
|
|
|
"whiteboard_id": message.payload?.presentations[0]?.id + "/" + numCurrentPage #not sure if always [0]
|
|
|
|
},
|
|
|
|
"header": {
|
|
|
|
"timestamp": new Date().getTime()
|
|
|
|
"name": "get_whiteboard_shapes_request"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@publishing(config.redis.channels.toBBBApps.whiteboard, requestMessage)
|
2014-05-31 00:32:00 +08:00
|
|
|
|
2014-05-31 02:23:13 +08:00
|
|
|
#strip off excess data, leaving only the current slide information
|
|
|
|
message.payload.currentPage = currentPage
|
|
|
|
message.payload.presentations = null
|
|
|
|
message.header.name = "presentation_page"
|
|
|
|
|
2014-05-31 02:56:24 +08:00
|
|
|
else if message.header?.name is 'presentation_shared_message'
|
|
|
|
currentPage = null
|
|
|
|
presentation = message.payload?.presentation
|
|
|
|
for page in presentation.pages
|
|
|
|
if page.current is true
|
|
|
|
currentPage = page
|
|
|
|
|
|
|
|
#strip off excess data, leaving only the current slide information
|
|
|
|
message.payload.currentPage = currentPage
|
|
|
|
message.payload.presentation = null
|
|
|
|
message.header.name = "presentation_page"
|
2014-05-31 03:12:58 +08:00
|
|
|
|
|
|
|
else if message.header?.name is 'presentation_page_changed_message'
|
|
|
|
message.payload.currentPage = message.payload?.page
|
|
|
|
message.payload?.page = null
|
|
|
|
message.header.name = "presentation_page"
|
|
|
|
|
|
|
|
console.log " Sending to Controller (In):" + message.header?.name
|
|
|
|
sendToController(message)
|
2014-05-22 23:22:13 +08:00
|
|
|
|
2014-05-26 22:24:56 +08:00
|
|
|
publishing: (channel, message) =>
|
2014-05-30 23:57:18 +08:00
|
|
|
console.log "Publishing #{message.header?.name}"
|
2014-05-26 22:24:56 +08:00
|
|
|
@pubClient.publish(channel, JSON.stringify(message))
|
|
|
|
|
2014-04-14 22:58:20 +08:00
|
|
|
sendToController = (message) ->
|
2014-04-24 04:18:25 +08:00
|
|
|
postal.publish
|
2014-04-24 05:37:19 +08:00
|
|
|
channel: config.redis.internalChannels.receive
|
2014-04-24 04:18:25 +08:00
|
|
|
topic: "broadcast"
|
2014-04-14 22:58:20 +08:00
|
|
|
data: message
|