module JamRuby # creates messages (implementation: protocol buffer) objects cleanly class MessageFactory CLIENT_TARGET = "client" SERVER_TARGET = "server" SESSION_TARGET_PREFIX = "session:" USER_TARGET_PREFIX = "user:" CLIENT_TARGET_PREFIX = "client:" def initialize() @type_values = {} Jampb::ClientMessage::Type.constants.each do |constant| @type_values[Jampb::ClientMessage::Type.const_get(constant)] = constant end end # given a string (bytes) payload, return a client message def parse_client_msg(payload) return Jampb::ClientMessage.parse(payload) end # create a login message using user/pass def login_with_user_pass(username, password, options = {}) login = Jampb::Login.new(:username => username, :password => password, :client_id => options[:client_id]) return Jampb::ClientMessage.new(:type => ClientMessage::Type::LOGIN, :route_to => SERVER_TARGET, :login => login) end # create a login message using token (a cookie or similar) def login_with_token(token, options = {}) login = Jampb::Login.new(:token => token, :client_id => options[:client_id]) return Jampb::ClientMessage.new(:type => ClientMessage::Type::LOGIN, :route_to => SERVER_TARGET, :login => login) end # create a login ack (login was successful) def login_ack(public_ip, client_id, token, heartbeat_interval, music_session_id, reconnected) login_ack = Jampb::LoginAck.new(:public_ip => public_ip, :client_id => client_id, :token => token, :heartbeat_interval => heartbeat_interval, :music_session_id => music_session_id, :reconnected => reconnected) return Jampb::ClientMessage.new(:type => ClientMessage::Type::LOGIN_ACK, :route_to => CLIENT_TARGET, :login_ack => login_ack) end # create a music session login message def login_music_session(music_session) login_music_session = Jampb::LoginMusicSession.new(:music_session => music_session) return Jampb::ClientMessage.new(:type => ClientMessage::Type::LOGIN_MUSIC_SESSION, :route_to => SERVER_TARGET, :login_music_session => login_music_session) end # create a music session login message ack (success or on failure) def login_music_session_ack(error, error_reason) login_music_session_ack = Jampb::LoginMusicSessionAck.new(:error => error, :error_reason => error_reason) return Jampb::ClientMessage.new(:type => ClientMessage::Type::LOGIN_MUSIC_SESSION_ACK, :route_to => CLIENT_TARGET, :login_music_session_ack => login_music_session_ack) end # create a music session 'leave session' message def leave_music_session(music_session) leave_music_session = Jampb::LeaveMusicSession.new(:music_session => music_session) return Jampb::ClientMessage.new(:type => ClientMessage::Type::LEAVE_MUSIC_SESSION, :route_to => SERVER_TARGET, :leave_music_session => leave_music_session) end # create a music session leave message ack (success or on failure) def leave_music_session_ack(error, error_reason) leave_music_session_ack = Jampb::LeaveMusicSessionAck.new(:error => error, :error_reason => error_reason) return Jampb::ClientMessage.new(:type => ClientMessage::Type::LEAVE_MUSIC_SESSION_ACK, :route_to => CLIENT_TARGET, :leave_music_session_ack => leave_music_session_ack) end # create a server bad state recovered msg def server_bad_state_recovered(original_message_id) recovered = Jampb::ServerBadStateRecovered.new() return Jampb::ClientMessage.new(:type => ClientMessage::Type::SERVER_BAD_STATE_RECOVERED, :route_to => CLIENT_TARGET, :server_bad_state_recovered => recovered, :in_reply_to => original_message_id) end # create a server error def server_generic_error(error_msg) error = Jampb::ServerGenericError.new(:error_msg => error_msg) return Jampb::ClientMessage.new(:type => ClientMessage::Type::SERVER_GENERIC_ERROR, :route_to => CLIENT_TARGET, :server_generic_error => error) end # create a server rejection error def server_rejection_error(error_msg) error = Jampb::ServerRejectionError.new(:error_msg => error_msg) return Jampb::ClientMessage.new(:type => ClientMessage::Type::SERVER_REJECTION_ERROR, :route_to => CLIENT_TARGET, :server_rejection_error => error) end # create a server rejection error def server_permission_error(original_message_id, error_msg) error = Jampb::ServerPermissionError.new(:error_msg => error_msg) return Jampb::ClientMessage.new(:type => ClientMessage::Type::SERVER_PERMISSION_ERROR, :route_to => CLIENT_TARGET, :server_permission_error => error, :in_reply_to => original_message_id) end # create a server bad state error def server_bad_state_error(original_message_id, error_msg) error = Jampb::ServerBadStateError.new(:error_msg => error_msg) return Jampb::ClientMessage.new(:type => ClientMessage::Type::SERVER_BAD_STATE_ERROR, :route_to => CLIENT_TARGET, :server_bad_state_error => error, :in_reply_to => original_message_id) end # create a friend joined session message def friend_session_join(session_id, user_id, username, photo_url) join = Jampb::FriendSessionJoin.new(:session_id => session_id, :user_id => user_id, :username => username, :photo_url => photo_url) return Jampb::ClientMessage.new(:type => ClientMessage::Type::FRIEND_SESSION_JOIN, :route_to => CLIENT_TARGET, :friend_session_join => join) end # create a musician joined session message def musician_session_join(session_id, user_id, username, photo_url) join = Jampb::MusicianSessionJoin.new(:session_id => session_id, :user_id => user_id, :username => username, :photo_url => photo_url) return Jampb::ClientMessage.new(:type => ClientMessage::Type::MUSICIAN_SESSION_JOIN, :route_to => CLIENT_TARGET, :musician_session_join => join) end # create a musician left session message def musician_session_depart(session_id, user_id, username, photo_url) left = Jampb::MusicianSessionDepart.new(:session_id => session_id, :user_id => user_id, :username => username, :photo_url => photo_url) return Jampb::ClientMessage.new(:type => ClientMessage::Type::MUSICIAN_SESSION_DEPART, :route_to => CLIENT_TARGET, :musician_session_depart => left) end # create a musician fresh session message def musician_session_fresh(session_id, user_id, username, photo_url) fresh = Jampb::MusicianSessionFresh.new(:session_id => session_id, :user_id => user_id, :username => username, :photo_url => photo_url) return Jampb::ClientMessage.new(:type => ClientMessage::Type::MUSICIAN_SESSION_FRESH, :route_to => CLIENT_TARGET, :musician_session_fresh => fresh) end # create a musician stale session message def musician_session_stale(session_id, user_id, username, photo_url) stale = Jampb::MusicianSessionStale.new(:session_id => session_id, :user_id => user_id, :username => username, :photo_url => photo_url) return Jampb::ClientMessage.new(:type => ClientMessage::Type::MUSICIAN_SESSION_STALE, :route_to => CLIENT_TARGET, :musician_session_stale => stale) end # create a user-joined session message def join_request(session_id, join_request_id, username, text) join_request = Jampb::JoinRequest.new(:join_request_id => join_request_id, :username => username, :text => text) return Jampb::ClientMessage.new(:type => ClientMessage::Type::JOIN_REQUEST, :route_to => SESSION_TARGET_PREFIX + session_id, :join_request => join_request) end # create a test message to send in session def test_session_message(session_id, msg) test = Jampb::TestSessionMessage.new(:msg => msg) return Jampb::ClientMessage.new(:type => ClientMessage::Type::TEST_SESSION_MESSAGE, :route_to => SESSION_TARGET_PREFIX + session_id, :test_session_message => test) end def session_invitation(receiver_id, sender_name, session_id, notification_id, created_at) session_invitation = Jampb::SessionInvitation.new(:sender_name => sender_name, :session_id => session_id, :notification_id => notification_id, :created_at => created_at) return Jampb::ClientMessage.new(:type => ClientMessage::Type::SESSION_INVITATION, :route_to => USER_TARGET_PREFIX + receiver_id, :session_invitation => session_invitation) end # create a friend update message def friend_update(user_id, name, photo_url, online, msg) friend = Jampb::FriendUpdate.new(:user_id => user_id, :name => name, :photo_url => photo_url, :online => online, :msg => msg) return Jampb::ClientMessage.new(:type => ClientMessage::Type::FRIEND_UPDATE, :route_to => USER_TARGET_PREFIX + user_id, :friend_update => friend) end # create a friend request message def friend_request(friend_request_id, user_id, name, photo_url, friend_id, msg, notification_id, created_at) friend_request = Jampb::FriendRequest.new(:friend_request_id => friend_request_id, :user_id => user_id, :name => name, :photo_url => photo_url, :friend_id => friend_id, :msg => msg, :notification_id => notification_id, :created_at => created_at) return Jampb::ClientMessage.new(:type => ClientMessage::Type::FRIEND_REQUEST, :route_to => USER_TARGET_PREFIX + friend_id, :friend_request => friend_request) end # create a friend request acceptance message def friend_request_accepted(friend_id, name, photo_url, user_id, msg, notification_id, created_at) friend_request_accepted = Jampb::FriendRequestAccepted.new(:friend_id => friend_id, :name => name, :photo_url => photo_url, :user_id => user_id, :msg => msg, :notification_id => notification_id, :created_at => created_at) return Jampb::ClientMessage.new(:type => ClientMessage::Type::FRIEND_REQUEST_ACCEPTED, :route_to => USER_TARGET_PREFIX + user_id, :friend_request_accepted => friend_request_accepted) end ############## P2P CLIENT MESSAGES ################# # send a request to do a ping def ping_request(client_id, from) ping_request = Jampb::PingRequest.new() return Jampb::ClientMessage.new(:type => ClientMessage::Type::PING_REQUEST, :route_to => CLIENT_TARGET_PREFIX + client_id, :from => from, :ping_request => ping_request) end # respond to a ping_request with an ack def ping_ack(client_id, from) ping_ack = Jampb::PingAck.new() return Jampb::ClientMessage.new(:type => ClientMessage::Type::PING_ACK, :route_to => CLIENT_TARGET_PREFIX + client_id, :from => from, :ping_ack => ping_ack) end # create a test message to send in session def test_client_message(client_id, from, msg) test = Jampb::TestClientMessage.new(:msg => msg) return Jampb::ClientMessage.new(:type => ClientMessage::Type::TEST_CLIENT_MESSAGE, :route_to => CLIENT_TARGET_PREFIX + client_id, :from => from, :test_client_message => test) end #################################################### # create a heartbeat def heartbeat() heartbeat = Jampb::Heartbeat.new return Jampb::ClientMessage.new(:type => ClientMessage::Type::HEARTBEAT, :route_to => SERVER_TARGET, :heartbeat => heartbeat) end # create a heartbeat ack def heartbeat_ack() heartbeat_ack = Jampb::HeartbeatAck.new() return Jampb::ClientMessage.new(:type => ClientMessage::Type::HEARTBEAT_ACK, :route_to => CLIENT_TARGET, :heartbeat_ack => heartbeat_ack) end # is this message directed to the server? def server_directed? msg return msg.route_to == MessageFactory::SERVER_TARGET end # is this message directed to the client? def client_directed? msg return msg.route_to.start_with? MessageFactory::CLIENT_TARGET_PREFIX end # is this message directed to a (music) session? def session_directed? msg return msg.route_to.start_with? MessageFactory::SESSION_TARGET_PREFIX end # is this message directed to a user? def user_directed? msg return msg.route_to.start_with? MessageFactory::USER_TARGET_PREFIX end def extract_session(msg) return msg.route_to[MessageFactory::SESSION_TARGET_PREFIX..-1] end def get_message_type msg return @type_values[msg.type] end end end