Created
October 18, 2013 15:53
-
-
Save lrvick/7043627 to your computer and use it in GitHub Desktop.
AngularJS service to connect to a websocket server (SockJS or pure WebSocket), manage reconnection, and allow the rest of the angular application to easily send/retrieve data from an open socket.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//TODO: make this a module | |
/** | |
* # SockJS socket management service | |
* | |
* Creates SockJS socket connection to server, re-connects on disconnection, | |
* and exports hooks to map handlers for various data interactions. | |
* | |
*/ | |
angular.module('app').factory | |
( 'socketService' | |
, [ '$rootScope' | |
, '$log' | |
, function | |
( $rootScope | |
, $log | |
){ | |
var createSocket = function(){ | |
// Get reference to port. | |
var port = (location.port != 80) ? ':' + location.port : ''; | |
socket = new SockJS | |
( '//' + document.domain + '' + port + '/api' | |
, '' | |
, { 'debug':true | |
, 'devel' : true | |
, 'protocols_whitelist': | |
[ 'xdr-streaming' | |
, 'xdr-polling' | |
, 'xhr-streaming' | |
, 'iframe-eventsource' | |
, 'iframe-htmlfile' | |
, 'xhr-polling' | |
, 'websocket' | |
] | |
} | |
); | |
/** | |
* ## Data interaction hooks | |
* | |
* Passes off core SockJS data interaction hooks to rest of application so | |
* callbacks can be cleanly defined externally for each event. | |
*/ | |
socket.onopen = function(){ | |
var args = arguments; | |
service.open = true; | |
service.timesOpened++; | |
// Attempted to connect. Note timestamp. | |
connectTimeStamps.push( new Date().getTime() ); | |
$rootScope.$broadcast( 'SOCKET_CLOSED' ); | |
if( service.handlers.onopen ){ | |
$rootScope.$apply | |
( function(){ | |
service.handlers.onopen.apply( socket, args ) | |
} | |
) | |
} | |
} | |
socket.onmessage = function( data ){ | |
var args = arguments; | |
try{ | |
args[0].data = JSON.parse(args[0].data); | |
} catch(e){ | |
// there should be a better way to do this | |
// but it is fast | |
} | |
if( service.handlers.onmessage ){ | |
$rootScope.$apply( | |
function(){ | |
service.handlers.onmessage.apply(socket, args); | |
} | |
) | |
} | |
} | |
socket.onclose = function(){ | |
service.open = false; | |
setTimeout( function(){ socket = createSocket(service); } , 3000 ); | |
var args = arguments; | |
$rootScope.$broadcast( 'SOCKET_OPEN' ); | |
if( service.handlers.onclose ){ | |
$rootScope.$apply( | |
function(){ | |
service.handlers.onclose.apply(socket,args); | |
} | |
) | |
} | |
} | |
return socket; | |
} | |
var service = | |
{ handlers : {} | |
, onopen: | |
function( callback ){ | |
this.handlers.onopen = callback; | |
} | |
, onmessage: | |
function( callback ){ | |
this.handlers.onmessage = callback; | |
} | |
, onclose: | |
function( callback ){ | |
this.handlers.onclose = callback; | |
} | |
, send: | |
function( data ){ | |
var msg = typeof(data) == "object" ? JSON.stringify(data) : data; | |
var status = socket.send(msg); | |
} | |
, open: false | |
}; | |
var socket = createSocket(); | |
return service; | |
} | |
] | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment