resolve merge conflict

This commit is contained in:
Jonathon Wilson 2012-10-16 20:35:16 -06:00
commit d74c7c7202
12 changed files with 250 additions and 111 deletions

View File

@ -0,0 +1,83 @@
/*
Message builder for communicating over the websocket
*/
(function(context, $) {
context.JK = context.JK || {};
var msg = context.JK.MessageType = {
LOGIN : "LOGIN",
LOGIN_ACK : "LOGIN_ACK",
LOGIN_MUSIC_SESSION : "LOGIN_MUSIC_SESSION",
LOGIN_MUSIC_SESSION_ACK : "LOGIN_MUSIC_SESSION_ACK",
USER_JOINED_MUSIC_SESSION : "USER_JOINED_MUSIC_SESSION",
LEAVE_MUSIC_SESSION : "LEAVE_MUSIC_SESSION",
LEAVE_MUSIC_SESSION_ACK : "LEAVE_MUSIC_SESSION_ACK",
HEARTBEAT : "HEARTBEAT",
TEST_SESSION_MESSAGE : "TEST_SESSION_MESSAGE",
PING_REQUEST : "PING_REQUEST",
PING_ACK : "PING_ACK",
PEER_MESSAGE : "PEER_MESSAGE",
SERVER_GENERIC_ERROR : "SERVER_GENERIC_ERROR",
SERVER_REJECTION_ERROR : "SERVER_REJECTION_ERROR"
};
var route_to = context.JK.RouteToPrefix = {
CLIENT : "client",
SESSION : "session",
SERVER : "server",
USER : "user"
};
var factory = {};
function client_container(type, target, inner) {
var type_field = type.toLowerCase();
var body = { "type" : type, "route_to" : target};
body[type_field] = inner;
return body;
}
function route_to_client(client_id) {
return route_to.CLIENT + ":" + client_id;
}
function route_to_session(session_id) {
return route_to.SESSION + ":" + session_id;
}
// ping the provided client_id
factory.ping = function(client_id) {
var data = {};
return client_container(msg.PING_REQUEST, route_to_client(client_id), data);
};
// create a login message using user/pass
factory.login_with_user_pass = function(username, password) {
var login = { username : username , password : password };
return client_container(msg.LOGIN, route_to.SERVER, login);
};
// create a login message using token (a cookie or similiar)
factory.login_with_token = function(token) {
var login = { token : token };
return client_container(msg.LOGIN, route_to.SERVER, login);
};
// create a music session login message
factory.login_music_session = function(music_session) {
var login_music_session = { music_session : music_session };
return client_container(msg.LOGIN_MUSIC_SESSION, route_to.SERVER, login_music_session);
};
// client-to-client message
factory.client_p2p_message = function(sender_client_id, receiver_client_id, message) {
var peer_message = { "message" : message };
var result = client_container(msg.PEER_MESSAGE, route_to_client(receiver_client_id), peer_message);
result.from = sender_client_id;
return result;
};
context.JK.MessageFactory = factory;
})(window, jQuery);

View File

@ -4,19 +4,21 @@
//
// The wrapper around the web-socket connection to the server
(function(context, $) {
var server = {};
context.JK = context.JK || {};
var logger = context.JK.logger;
var msg_factory = context.JK.MessageFactory;
// Let socket.io know where WebSocketMain.swf is
WEB_SOCKET_SWF_LOCATION = "assets/flash/WebSocketMain.swf";
var server = {};
server.socket = {};
server.singedIn = false;
server.signedIn = false;
server.clientID = "";
server.publicIP = "";
server.dispatchTable = {};
// TODO: Create the message factory here
//server.messageFactory = context.message_factory;
server.registerMessageCallback = function(messageType, callback) {
if (server.dispatchTable[messageType] === undefined) {
server.dispatchTable[messageType] = [];
@ -42,11 +44,7 @@
};
server.connect = function() {
server.registerMessageCallback(
context.Messages.LOGIN_ACK,
function() { server.signedIn = true; }
);
logger.log("server.connect");
server.socket = new WebSocket(gon.websocket_gateway_uri);
server.socket.onopen = server.onOpen;
server.socket.onmessage = server.onMessage;
@ -54,25 +52,24 @@
};
server.onOpen = function() {
logger.log('server.onOpen');
logger.log("server.onOpen");
var token, loginMessage;
token = $.cookie("remember_token");
loginMessage = context.message_factory.login_with_token(token);
loginMessage = msg_factory.login_with_token(token);
server.send(loginMessage);
};
server.onMessage = function(e) {
logger.log('server.onMessage');
logger.log("server.onMessage");
var message = JSON.parse(e.data),
messageType = message.type.toLowerCase(),
payload = message[messageType],
callbacks = server.dispatchTable[message.type];
if (callbacks !== undefined) {
for(var i = callbacks.length; i--;) {
callbacks[i](messageType, payload);
var len = callbacks.length;
for(var i = 0; i < len; i++) {
callbacks[i](message, payload);
}
}
else {
@ -82,13 +79,24 @@
server.onClose = function() {
logger.log("Socket to server closed.");
if (context.jamClient !== undefined)
{
context.jamClient.connected = false;
}
// TODO: reconnect
};
server.send = function(message) {
var jsMessage = JSON.stringify(message);
logger.log('server.send(' + jsMessage + ')');
server.socket.send(jsMessage);
logger.log("server.send(" + jsMessage + ")");
if (server !== undefined && server.socket !== undefined && server.socket.send !== undefined) {
server.socket.send(jsMessage);
} else {
logger.log("Dropped message because server connection is closed.");
}
};
server.loginSession = function(sessionId) {
@ -100,10 +108,50 @@
return;
}
loginMessage = context.message_factory.login_jam_session(sessionId);
loginMessage = msg_factory.login_jam_session(sessionId);
server.send(loginMessage);
};
context.JamServer = server;
server.sendP2PMessage = function(receiver_id, message) {
logger.log("P2P message from [" + server.clientID + "] to [" + receiver_id + "]: " + message);
var outgoing_msg = msg_factory.client_p2p_message(server.clientID, receiver_id, message);
server.send(outgoing_msg);
};
context.JK.JamServer = server;
// Message callbacks
server.registerMessageCallback(context.JK.MessageType.LOGIN_ACK, function(header, payload) {
server.signedIn = true;
server.clientID = payload.client_id;
server.publicIP = payload.public_ip;
if (context.jamClient !== undefined)
{
context.jamClient.connected = true;
context.jamClient.clientID = server.clientID;
}
});
server.registerMessageCallback(context.JK.MessageType.PEER_MESSAGE, function(header, payload) {
if (context.jamClient !== undefined)
{
context.jamClient.P2PMessageReceived(header.from, payload.message);
}
});
server.registerMessageCallback(context.JK.MessageType.LOGIN_MUSIC_SESSION_ACK, function(header, payload) {
if (context.jamClient !== undefined)
{
// TODO: modify the LOGIN_MUSIC_SESSION_ACK message to include session_id
context.jamClient.JoinSession({ sessionID : payload.session_id});
}
});
// Callbacks from jamClient
if (context.jamClient !== undefined)
{
context.jamClient.SendP2PMessage.connect(server.sendP2PMessage);
}
})(window, jQuery);

View File

@ -34,6 +34,7 @@ Message from Seth on sequence for creating/joining sessions:
function(response) {
var newSessionId = response.id;
self.location = '#/session/' + newSessionId;
context.JK.joinMusicSession(newSessionId);
}
);
evt.preventDefault();

View File

@ -0,0 +1,34 @@
(function(context,$) {
context.JK = context.JK || {};
context.JK.joinMusicSession = function(session_id) {
var logger = context.JK.logger;
var server = context.JK.JamServer;
var client = context.jamClient;
if (!server.signedIn)
{
logger.log("Can't join a session because the client is not connected.");
return;
}
logger.log("Joining session: " + session_id);
var data = { client_id: server.clientID, ip_address: server.publicIP };
var url = "/api/sessions/" + session_id + "/participants";
$.ajax({
type: "POST",
url: url,
data: data
}).done(
function(response) {
if (client !== undefined)
{
client.JoinSession({ sessionID: session_id });
}
}
);
};
})(window,jQuery);

View File

@ -1,64 +0,0 @@
/*
Message builder for communicating over the websocket
*/
(function(context) {
var CLIENT_TARGET = "client";
var SERVER_TARGET = "server";
var SESSION_TARGET_PREFIX = "session:";
var USER_TARGET_PREFIX = "user:";
var CLIENT_TARGET_PREFIX = "client:";
var msg = context.Messages = {
LOGIN : "LOGIN",
LOGIN_ACK : "LOGIN_ACK",
LOGIN_MUSIC_SESSION : "LOGIN_MUSIC_SESSION",
LOGIN_MUSIC_SESSION_ACK : "LOGIN_MUSIC_SESSION_ACK",
USER_JOINED_MUSIC_SESSION : "USER_JOINED_MUSIC_SESSION",
LEAVE_MUSIC_SESSION : "LEAVE_MUSIC_SESSION",
LEAVE_MUSIC_SESSION_ACK : "LEAVE_MUSIC_SESSION_ACK",
HEARTBEAT : "HEARTBEAT",
TEST_SESSION_MESSAGE : "TEST_SESSION_MESSAGE",
PING_REQUEST: "PING_REQUEST",
PING_ACK: "PING_ACK",
SERVER_GENERIC_ERROR : "SERVER_GENERIC_ERROR",
SERVER_REJECTION_ERROR : "SERVER_REJECTION_ERROR"
};
var message_factory = {};
function client_container(type, target, inner) {
var type_field = type.toLowerCase();
var body = { "type" : type, "route_to" : target};
body[type_field] = inner;
return body;
}
// ping the provided client_id
message_factory.ping = function(client_id) {
var data = {};
var target = CLIENT_TARGET_PREFIX + client_id;
return client_container(msg.PING_REQUEST, target, data);
};
// create a login message using user/pass
message_factory.login_with_user_pass = function(username, password) {
var login = { username : username , password : password };
return client_container(msg.LOGIN, SERVER_TARGET, login);
};
// create a login message using token (a cookie or similiar)
message_factory.login_with_token = function(token) {
var login = { token : token };
return client_container(msg.LOGIN, SERVER_TARGET, login);
};
// create a music session login message
message_factory.login_music_session = function(music_session) {
var login_music_session = { music_session : music_session };
return client_container(msg.LOGIN_MUSIC_SESSION, SERVER_TARGET, login_music_session);
};
window.message_factory = message_factory;
})(window);

View File

@ -8,22 +8,22 @@
context.JK = context.JK || {};
context.JK.Messaging = function(app) {
if ("undefined" === typeof(context.JamServer))
if ("undefined" === typeof(context.JK.JamServer))
return;
// Alias some of the globals for less typing.
var logger = context.JK.logger;
var server = context.JamServer;
var messages = context.Messages;
var msg_factory = context.message_factory;
var server = context.JK.JamServer;
var messages = context.JK.MessageType;
var msg_factory = context.JK.MessageFactory;
var myClientId = null;
var myPingTimer = null;
var pingCount = 0;
var maxPings = 5;
function logMessage(messageType, payload) {
logger.debug(messageType + ": " + JSON.stringify(payload));
function logMessage(header, payload) {
logger.debug(header.type + ": " + JSON.stringify(payload));
}
function pingMyself() {
@ -38,8 +38,8 @@
}
}
function loggedIn(messageType, payload) {
logger.debug('Logged In handler: ' + messageType + ':' + JSON.stringify(payload));
function loggedIn(header, payload) {
logger.debug('Logged In handler: ' + header.type + ':' + JSON.stringify(payload));
myClientId = payload.client_id;
myPingTimer = context.setInterval(pingMyself, 1000);
}
@ -54,8 +54,8 @@
*/
this.register = function() {
for (var message in messages) {
logger.debug("registering logger.debug: " + message);
context.JamServer.registerMessageCallback(message, logMessage);
logger.debug("registering " + message);
server.registerMessageCallback(message, logMessage);
}
registerLoginPinger();

View File

@ -1,7 +1,8 @@
class ApiUsersController < ApplicationController
before_filter :signed_in_user, only: [:index, :edit, :update, :delete,
:friend_request_index, :friend_request_create,
:friend_request_index, :friend_request_show,
:friend_request_create, :friend_request_update,
:friend_index, :friend_destroy]
respond_to :json
@ -10,35 +11,61 @@ class ApiUsersController < ApplicationController
@users = User.paginate(page: params[:page])
end
def show
@user = User.find(params[:id])
end
def create
@user = User.new()
@user.email = params[:email]
@user.creator = current_user
@user.description = params[:description]
@user.save
respond_with @user, responder: ApiResponder, :location => api_user_detail_url(@user)
end
def show
@user = User.find(params[:id])
end
def delete
@user = User.find(params[:id])
@user.delete
respond_with @user, responder: ApiResponder
end
def friend_request_index
end
def friend_request_create
# get all outgoing and incoming friend requests
@friend_requests = FriendRequest.where("(friend_id='#{params[:id]}' OR user_id='#{params[:id]}') AND accepted is null")
end
def friend_request_show
@friend_request = FriendRequest.find(params[:id])
end
def friend_request_create
@friend_request = FriendRequest.new()
@friend_request.user_id = params[:user_id]
@friend_request.friend_id = params[:friend_id]
@friend_request.save
respond_with @friend_request, responder: ApiResponder, :location => api_friend_request_detail_url(@friend_request)
end
def friend_request_update
@friend_request = FriendRequest.find(params[:id])
@friend_request.accepted = params[:accepted]
@friend_request.save
# create both records for this friendship
if @friend_request.accepted?
@friendship = Friendship.new()
@friendship.user_id = @friend_request.user_id
@friendship.friend_id = @friend_request.friend_id
@friendship.save
@friendship = Friendship.new()
@friendship.user_id = @friend_request.friend_id
@friendship.friend_id = @friend_request.user_id
@friendship.save
end
respond_with @friend_request, responder: ApiResponder
end
def friend_index
@ -47,7 +74,9 @@ class ApiUsersController < ApplicationController
end
def friend_destroy
# clean up both records representing this "friendship"
JamRuby::Friendship.delete_all "(user_id = '#{params[:id]}' AND friend_id = '#{params[:friend_id]}') OR (user_id = '#{params[:friend_id]}' AND friend_id = '#{params[:id]}')"
respond_with responder: ApiResponder
end
end

View File

@ -1,3 +1,3 @@
object @user.friends
attributes :id, :name, :online
attributes :id, :name, :email, :online

View File

@ -0,0 +1,3 @@
object @friend_requests
extends "api_users/friend_request_show"

View File

@ -0,0 +1,3 @@
object @friend_request
attributes :id, :user_id, :friend_id, :accepted, :created_at

View File

@ -454,7 +454,8 @@
var messaging = new JK.Messaging(jk);
messaging.register();
window.JamServer.connect();
var jam_server = JK.JamServer;
jam_server.connect();
})
</script>

View File

@ -7,6 +7,7 @@ SampleApp::Application.routes.draw do
resources :users
resources :music_sessions
resources :friend_requests
resources :sessions, only: [:new, :create, :destroy]
@ -34,16 +35,16 @@ SampleApp::Application.routes.draw do
# users
match '/users' => 'api_users#index', :via => :get
match '/users' => 'api_users#create', :via => :post
match '/users/:id' => 'api_users#show', :via => :get, :as => 'api_user_detail'
match '/users/:id' => 'api_users#edit', :via => :put
match '/users' => 'api_users#create', :via => :post
match '/users/:id' => 'api_users#update', :via => :put
match '/users/:id' => 'api_users#destroy', :via => :delete
# friend requests
match '/users/:id/friend_requests' => 'api_users#friend_request_index', :via => :get
match '/users/:id/friend_requests' => 'api_users#friend_request_create', :via => :post
match '/users/:id/friends/:friend_request_id' => 'api_users#friend_request_show', :via => :get, :as => 'api_user_friend_request_detail'
match '/users/:id/friends/:friend_request_id' => 'api_users#friend_request_update', :via => :put
match '/friend_requests/:id' => 'api_users#friend_request_show', :via => :get, :as => 'api_friend_request_detail'
match '/friend_requests' => 'api_users#friend_request_create', :via => :post
match '/friend_requests/:id' => 'api_users#friend_request_update', :via => :put
# friends
match '/users/:id/friends' => 'api_users#friend_index', :via => :get