// The wrapper around the web-socket connection to the server (function(context, $) { "use strict"; context.JK = context.JK || {}; var logger = context.JK.logger; var msg_factory = context.JK.MessageFactory; // Let socket.io know where WebSocketMain.swf is context.WEB_SOCKET_SWF_LOCATION = "assets/flash/WebSocketMain.swf"; var server = {}; server.socket = {}; server.signedIn = false; server.clientID = ""; server.publicIP = ""; server.dispatchTable = {}; server.socketClosedListeners = []; server.connected = false; // handles logic if the websocket connection closes, and if it was in error then also prompt for reconnect function closedCleanup(in_error) { if(server.connected) { server.connected = false; context.JK.CurrentSessionModel.onWebsocketDisconnected(in_error); // notify anyone listening that the socket closed var len = server.socketClosedListeners.length; for(var i = 0; i < len; i++) { try { server.socketClosedListeners[i](in_error); } catch (ex) { logger.warn('exception in callback for websocket closed event:' + ex); } } } } server.registerOnSocketClosed = function(callback) { server.socketClosedListeners.push(callback); } server.registerMessageCallback = function(messageType, callback) { if (server.dispatchTable[messageType] === undefined) { server.dispatchTable[messageType] = []; } server.dispatchTable[messageType].push(callback); }; server.unregisterMessageCallback = function(messageType, callback) { if (server.dispatchTable[messageType] !== undefined) { for(var i = server.dispatchTable[messageType].length; i--;) { if (server.dispatchTable[messageType][i] === callback) { server.dispatchTable[messageType].splice(i, 1); break; } } } if (server.dispatchTable[messageType].length === 0) { delete server.dispatchTable[messageType]; } }; server.connect = function() { logger.log("server.connect"); var uri = context.JK.websocket_gateway_uri; // Set in index.html.erb. //var uri = context.gon.websocket_gateway_uri; // Leaving here for now, as we're looking for a better solution. server.socket = new context.WebSocket(uri); server.socket.onopen = server.onOpen; server.socket.onmessage = server.onMessage; server.socket.onclose = server.onClose; }; server.close = function(in_error) { logger.log("closing websocket"); server.socket.close(); closedCleanup(in_error); } server.rememberLogin = function() { var token, loginMessage; token = $.cookie("remember_token"); loginMessage = msg_factory.login_with_token(token, null); server.send(loginMessage); }; server.onOpen = function() { logger.log("server.onOpen"); server.rememberLogin(); }; server.onMessage = function(e) { var message = JSON.parse(e.data), messageType = message.type.toLowerCase(), payload = message[messageType], callbacks = server.dispatchTable[message.type]; logger.log("server.onMessage:" + messageType + " payload:" + JSON.stringify(payload)); if (callbacks !== undefined) { var len = callbacks.length; for(var i = 0; i < len; i++) { try { callbacks[i](message, payload); } catch (ex) { logger.warn('exception in callback for websocket message:' + ex); } } } else { logger.log("Unexpected message type %s.", message.type); } }; server.onClose = function() { logger.log("Socket to server closed."); closedCleanup(true); }; server.send = function(message) { var jsMessage = JSON.stringify(message); 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) { var loginMessage; if (!server.signedIn) { logger.log("Not signed in!"); // TODO: surface the error return; } loginMessage = msg_factory.login_jam_session(sessionId); server.send(loginMessage); }; 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; logger.debug("Handling LOGIN_ACK. Updating client id to " + payload.client_id); server.clientID = payload.client_id; server.publicIP = payload.public_ip; server.connected = true; if (context.jamClient !== undefined) { logger.debug("... (handling LOGIN_ACK) Updating backend client, connected to true and clientID to " + payload.client_id); 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); } }); // Callbacks from jamClient if (context.jamClient !== undefined) { context.jamClient.SendP2PMessage.connect(server.sendP2PMessage); } })(window, jQuery);