jam-cloud/ruby/lib/jam_ruby/mq_router.rb

135 lines
5.4 KiB
Ruby
Raw Permalink Normal View History

require 'eventmachine'
class MQRouter
# monostate pattern:
# You can initialize MQRouter instances as you want,
# but ultimately there are internal static state variables to represent global MQ exchange connections
class << self
attr_accessor :client_exchange, :user_exchange, :subscription_exchange
@@log = Logging.logger[MQRouter]
end
def access_music_session(music_session, user)
if music_session.nil?
raise ArgumentError, 'specified session not found'
end
if !music_session.access? user
raise JamPermissionError, 'not allowed to join the specified session'
end
return music_session
end
# sends a message to a session on behalf of a user
# if this is originating in the context of a client, it should be specified as :client_id => "value"
# client_msg should be a well-structure message (jam-pb message)
def user_publish_to_session(music_session, user, client_msg, sender = {:client_id => nil})
access_music_session(music_session, user)
client_ids = music_session.get_connection_ids(as_musician: true, exclude_client_id: sender[:client_id])
publish_to_session(music_session.id, client_ids, client_msg.to_s, sender)
end
2013-03-23 07:50:01 +00:00
# sends a message to a session from the server
# no access check as with user_publish_to_session
# client_msg should be a well-structure message (jam-pb message)
def server_publish_to_session(music_session, client_msg, sender = {:client_id => nil})
# gather up client_ids in the session
client_ids = music_session.get_connection_ids(as_musician: true, exclude_client_id: sender[:client_id])
publish_to_session(music_session.id, client_ids, client_msg.to_s, sender)
end
# sends a message to a session AND fans/listeners from the server
# client_msg should be a well-structure message (jam-pb message)
def server_publish_to_everyone_in_session(music_session, client_msg, sender = {:client_id => nil})
# gather up client_ids in the session
client_ids = music_session.get_connection_ids(exclude_client_id: sender[:client_id])
publish_to_session(music_session.id, client_ids, client_msg.to_s, sender)
end
# sends a message to a client with no checking of permissions (RAW USAGE)
# this method deliberately has no database interactivity/active_record objects
def publish_to_client(client_id, client_msg, sender = {:client_id => ""})
@@log.error "EM not running in publish_to_client" unless EM.reactor_running?
EM.schedule do
sender_client_id = sender[:client_id]
@@log.debug "publishing to client:#{client_id} from client:#{sender_client_id}"
# put it on the topic exchange for clients
self.class.client_exchange.publish(client_msg, :routing_key => "client.#{client_id}")
end
end
# sends a message to all clients
def publish_to_all_clients(client_msg)
publish_to_client(MessageFactory::ALL_NATIVE_CLIENTS, client_msg)
end
2016-01-30 22:08:54 +00:00
# sends a message to all clients
def publish_to_active_clients(client_msg)
publish_to_client(MessageFactory::ALL_ACTIVE_CLIENTS, client_msg)
end
# sends a message to a session with no checking of permissions (RAW USAGE)
# this method deliberately has no database interactivity/active_record objects
def publish_to_session(music_session_id, client_ids, client_msg, sender = {:client_id => nil})
@@log.error "EM not running in publish_to_session" unless EM.reactor_running?
EM.schedule do
sender_client_id = sender[:client_id]
# iterate over each person in the session, and send a p2p message
client_ids.each do |client_id|
@@log.debug "publishing to session:#{music_session_id} / client:#{client_id} from client:#{sender_client_id}"
# put it on the topic exchange for clients
self.class.client_exchange.publish(client_msg, :routing_key => "client.#{client_id}")
end
end
end
# sends a message to a user with no checking of permissions (RAW USAGE)
# this method deliberately has no database interactivity/active_record objects
def publish_to_user(user_id, user_msg, sender = {:client_id => nil})
@@log.error "EM not running in publish_to_user" unless EM.reactor_running?
2014-01-15 22:15:33 +00:00
EM.schedule do
sender_client_id = sender[:client_id]
@@log.debug "publishing to user:#{user_id} from server from client:#{sender_client_id}"
# put it on the topic exchange for users
2013-03-23 07:50:01 +00:00
self.class.user_exchange.publish(user_msg, :routing_key => "user.#{user_id}")
end
end
# sends a message to a list of friends with no checking of permissions (RAW USAGE)
# this method deliberately has no database interactivity/active_record objects
def publish_to_friends(friend_ids, user_msg, from_user_id)
@@log.error "EM not running in publish_to_friends" unless EM.reactor_running?
EM.schedule do
friend_ids.each do |friend_id|
2014-01-02 19:57:16 +00:00
@@log.debug "publishing to friend:#{friend_id} from user/band #{from_user_id}"
# put it on the topic exchange for users
2013-03-23 07:50:01 +00:00
self.class.user_exchange.publish(user_msg, :routing_key => "user.#{friend_id}")
end
end
end
def publish_to_subscription(type, id, msg)
@@log.error "EM not running in publish_to_subscription" unless EM.reactor_running?
EM.schedule do
routing_key = "subscription.#{type}.#{id}"
@@log.debug "publishing to #{routing_key} from server"
# put it on the topic exchange for users
self.class.subscription_exchange.publish(msg, :routing_key => routing_key)
end
end
end