144 lines
5.0 KiB
JavaScript
144 lines
5.0 KiB
JavaScript
(function(context, $) {
|
|
|
|
"use strict";
|
|
|
|
context.JK = context.JK || {};
|
|
|
|
context.JK.SessionLatency = function(jamClient) {
|
|
|
|
var logger = context.JK.logger;
|
|
var sessionPingsOut = {};
|
|
var clientsToSessions = {};
|
|
var sessionLatency = {};
|
|
var subscribers = {};
|
|
|
|
function getSortScore(sessionId) {
|
|
return sessionLatency[sessionId].sortScore;
|
|
}
|
|
|
|
function ensureSessionLatencyEntry(sessionId) {
|
|
if (!(sessionId in sessionLatency)) {
|
|
sessionLatency[sessionId] = {
|
|
clientLatencies: {},
|
|
averageLatency: 0
|
|
};
|
|
}
|
|
}
|
|
|
|
function setInitialSortScore(session) {
|
|
var i,
|
|
p,
|
|
score = 0,
|
|
participant = null;
|
|
|
|
// user has invitations for this session
|
|
if ("invitations" in session) {
|
|
score += 2;
|
|
}
|
|
for (i=0, p=session.participants.length; i<p; i++) {
|
|
participant = session.participants[i];
|
|
// this session participant is a friend
|
|
if (participant !== undefined && participant.user !== undefined && participant.user.is_friend) {
|
|
score += 1;
|
|
break;
|
|
}
|
|
}
|
|
ensureSessionLatencyEntry(session.id);
|
|
sessionLatency[session.id].sortScore = score;
|
|
}
|
|
|
|
function sessionPings(session) {
|
|
setInitialSortScore(session);
|
|
$.each(session.participants, function(index, participant) {
|
|
var clientID = participant.client_id;
|
|
clientsToSessions[clientID] = session.id;
|
|
if (!(session.id in sessionPingsOut)) {
|
|
sessionPingsOut[session.id] = 0;
|
|
}
|
|
sessionPingsOut[session.id]++;
|
|
var jsFunction = "JK.Callbacks.clientPingResponse";
|
|
var timeoutFunction = "JK.Callbacks.clientPingTimeout";
|
|
|
|
console.log("jamClient.TestLatency")
|
|
console.time('jamClient.TestLatency');
|
|
jamClient.TestLatency(clientID, jsFunction, timeoutFunction);
|
|
console.timeEnd('jamClient.TestLatency');
|
|
});
|
|
}
|
|
|
|
function clientPingResponse(response) {
|
|
logger.debug("clientPingResponse");
|
|
logger.debug(response);
|
|
var sessionId = clientsToSessions[response.clientID];
|
|
sessionPingsOut[sessionId]--;
|
|
updateSessionLatency(sessionId, response);
|
|
for (var k in subscribers) {
|
|
if (typeof(subscribers[k]) === 'function') {
|
|
subscribers[k](sessionId);
|
|
}
|
|
}
|
|
}
|
|
|
|
function clientPingTimeout(clientId) {
|
|
logger.warn("TIMEOUT during client ping:" + clientId);
|
|
logger.warn("calling clientPingResponse directly with 1,000 MS latency");
|
|
var response = { clientID: clientId, latency: 1000 };
|
|
clientPingResponse(response);
|
|
}
|
|
|
|
function updateSessionLatency(sessionId, latencyResponse) {
|
|
ensureSessionLatencyEntry(sessionId);
|
|
var sl = sessionLatency[sessionId];
|
|
sl.clientLatencies[latencyResponse.clientID] = latencyResponse.latency;
|
|
sl.averageLatency = latencyAverage(sl.clientLatencies);
|
|
sl.sortScore = updateSortScore(sessionId, sl.averageLatency);
|
|
}
|
|
|
|
function updateSortScore(sessionId, averageLatency) {
|
|
var newScore = sessionLatency[sessionId].sortScore;
|
|
if (!(newScore)) {
|
|
newScore = 0;
|
|
}
|
|
if (!averageLatency) {
|
|
return newScore;
|
|
}
|
|
var base = Math.floor(newScore);
|
|
newScore = base + (1/averageLatency);
|
|
return newScore;
|
|
}
|
|
|
|
function latencyAverage(clientLatencies) {
|
|
var total = 0;
|
|
var count = 0;
|
|
$.each(clientLatencies, function(index, latency) {
|
|
total += latency;
|
|
count++;
|
|
});
|
|
return total/count;
|
|
}
|
|
|
|
function sessionInfo(sessionId) {
|
|
return sessionLatency[sessionId];
|
|
}
|
|
|
|
function subscribe(subscriberKey, cb) {
|
|
subscribers[subscriberKey] = cb;
|
|
}
|
|
|
|
this.sessionPings = sessionPings;
|
|
this.sessionInfo = sessionInfo;
|
|
this.getSortScore = getSortScore;
|
|
this.subscribe = subscribe;
|
|
this.clientPingResponse = clientPingResponse;
|
|
this.clientPingTimeout = clientPingTimeout;
|
|
|
|
// Register clientPingResponse on this instance as a static function
|
|
// so that the JavascriptBridge native code can invoke it with a string.
|
|
context.JK.Callbacks.makeStatic("clientPingResponse", this.clientPingResponse, this);
|
|
context.JK.Callbacks.makeStatic("clientPingTimeout", this.clientPingTimeout, this);
|
|
|
|
return this;
|
|
};
|
|
|
|
|
|
})(window, jQuery); |