Skip to content

Instantly share code, notes, and snippets.

@clintberry
Created September 3, 2013 06:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save clintberry/6420200 to your computer and use it in GitHub Desktop.
Save clintberry/6420200 to your computer and use it in GitHub Desktop.
Websocket service with pending functions until websocket opened.
'use strict';
angular.module('guiApp')
.service('Websocket', function Websocket($q, $rootScope, PubSub) {
var Service = {}; // Object to return for the service
var callbacks = {}; // Keep all pending requests here until they get responses
var currentCallbackId = 0; // Create a unique callback ID to map requests to responses
var ws = null; // Initialize our websocket variable
var connectStatus = false; // Is the websocket connected?
var authStatus = false; // Are we authorized?
var disconnects = 0; // How many times have we disconnected and retried (used for calculating retry wait)
var retryWaitMax = 120; // Maximum amount of time to wait for a re-connect attempt
var pendingRequests = []; // Any requests coming in before we connect are stored and run when connected
Service.connect = function(address) {
console.log('Connecting to websocket...');
address = address || 'http://localhost:7777/freeswitch/';
ws = new window.SockJS(address);
ws.onopen = function() {
console.log('Socket has been opened!');
connectStatus = true;
PubSub.broadcast('socket_connect', {});
authorize();
};
ws.onmessage = function(message) {
listener(JSON.parse(message.data));
};
ws.onclose = function() {
console.log('Socket has closed');
connectStatus = false;
PubSub.broadcast('socket_close', {});
disconnects++;
var retryWait = Math.pow(2, disconnects);
if(retryWait > retryWaitMax) {
disconnects--;
retryWait = retryWaitMax;
}
console.log('Retrying in ' + retryWait + ' seconds...');
setTimeout(Service.connect, retryWait * 1000);
};
};
function authorize(user, password) {
var creds = user + password;
authStatus = true;
PubSub.broadcast('socket_authorize', creds);
return true;
}
function sendRequest(request) {
var defer = $q.defer();
var callbackId = getCallbackId();
callbacks[callbackId] = {
time: new Date(),
cb:defer
};
request.callback_id = callbackId;
if(!connectStatus) {
console.log('Saving request until connected');
pendingRequests.push(request);
}
else {
console.log('Sending request', request);
ws.send(JSON.stringify(request));
}
return defer.promise;
}
function listener(data) {
var messageObj = data;
console.log('Received data from websocket: ', messageObj);
// If an object exists with callback_id in our callbacks object, resolve it
if(callbacks.hasOwnProperty(messageObj.callback_id)) {
console.log(callbacks[messageObj.callback_id]);
$rootScope.$apply(callbacks[messageObj.callback_id].cb.resolve(messageObj.data));
delete callbacks[messageObj.callbackID];
}
else if(messageObj.hasOwnProperty('Event-Name')) {
PubSub.broadcast(messageObj['Event-Name'], messageObj);
}
}
// This creates a new callback ID for a request
function getCallbackId() {
currentCallbackId += 1;
if(currentCallbackId > 10000) {
currentCallbackId = 0;
}
return currentCallbackId;
}
/**
* Subscribe to a freeswitch event
* @param {String} eventName
* @return {Promise}
*/
Service.subscribe = function(eventName) {
var request = {
type: 'subscribe',
event_name: eventName
};
// Storing in a variable for clarity on what sendRequest returns
var promise = sendRequest(request);
return promise;
};
Service.connect();
return Service;
});
@clintberry
Copy link
Author

The key thing to note here is in sendRequest function on line #62 - we check to see if we are connected to the websocket, if not, we store that request for later. What has NOT been implemented in this gist yet, is when the websocket connects, it needs to check to see if there are any pending requests and send them off.
Hope that helps!

@4day
Copy link

4day commented Aug 13, 2014

line #80 must be delete callbacks[messageObj.callback_id];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment