Sunday, May 28, 2023

QoS Indicator for Citrix StoreFront

After the successful release of Setting user Expectations, which showed you how to add a QoS (Quality of Service) indicator to the NetScaler logon screen, I've had requests for a similar indicator for StoreFront. 


As a bonus, we will have the display auto-refresh at a custom-defined interval. We will set it to every 15 seconds, but you can very easily modify that.

Note: The code in this post has been written for StoreFront version 2203. The code may need to be tweaked for other versions of StoreFront.

All of the modifications may be done via updates within the custom directory of the site, which means that they will be replicated to all servers in the StoreFront group when you propagate. 

The following code should be added to script.js (in the custom directory):

  // QoS refresh interval
  var refreshIntervalSecs = 15;

   // QoS latency ranges - max value for range, class name for graphic, legend
   var aLatencyRanges = 
[[20,"qos-excellent","Excellent"],
[50,"qos-verygood","Very Good"],
[75,"qos-good","Good"],
[150,"qos-fair","Fair"],
[99999,"qos-poor","Poor"]];

    // image to download to calculate Time To First Byte (TTFB) 
    var testImgUrl = "custom/images/FourBars.png";

//This method calculates the time it takes for the image to load 
function checkLatency(url, callback) {
var t=[], n=2, tcp, rtt;
var ld = function() {
   t.push(+new Date);
   if(t.length > n) {
rtt=t[2]-t[1];
callback(rtt);
   }
   else {
var img = new Image;
img.onload = ld;
img.src=url+"?" + Math.random() + '=' + new Date;
   }
};
ld();
}

function displayQoS(latency) {

   // for refresh, we need to remove the current image class
   var currClass = $("#QoSimage").attr('class');
   $("#QoSimage").removeClass(currClass);

   for (i=0; i<aLatencyRanges.length;i++) {
if(latency<=aLatencyRanges[i][0]) {
var QoSclass = aLatencyRanges[i][1];
var QoSinfo = aLatencyRanges[i][2] + ' (' + latency + ' ms.)';
$("#QoSval").html(QoSinfo);
$("#QoSimage").addClass(QoSclass);
break;
}
   }
}

function RunQoS() {
  // file to use for testing, and callback routine
  checkLatency(testImgUrl, displayQoS);
}

// wait until StoreFront has been loaded
$(document).ready(function() {

   // add the QoS DIVs
   var $qos = $("<div id='QoSinfo'><a href='custom/ConnectionQuality.html'><div id='QoSimage'></div><div id='QoSRight'><div id='QoStext'>Connection Quality:</div><div id='QoSval'></div></div></a></div>");

   // Important: This selector is for StoreFront version 2203
   //                  The selector may be different for other versions of StoreFront
   $qos.insertBefore("#searchBtn");

   // run QoS ... run twice the first time to remove handshake overhead
   RunQoS(); RunQoS();

   // now set up auto refresh
   var refreshIntervalms = refreshIntervalSecs * 1000;
   window.setInterval(RunQoS, refreshIntervalms); 
});


Let's style the above (size, color, font, etc.) by adding the following to style.css (in the custom directory):

#QoSinfo {
margin-right: 100px;
width: 200px;
margin-top: 20px;
height: 40px;
color: white;
}

#QoSimage {
height: 40px;
width: 70px;
margin-top: -7px;
position: absolute;
margin-right: -50px;
}

#QoSRight {
display: inline-block;
font-size: 12px;
height: 40px;
margin-left: 77px;
}

#QoSval,#QoStext {
font-style: italic;
color:white;
font-weight: bold;
}

.qos-excellent {
background-image : url('../custom/images/FourBars.png'); 
background-repeat: no-repeat;
background-position: center;
}

.qos-verygood {
background-image : url('../custom/images/ThreeBars.png'); 
background-repeat: no-repeat;
background-position: center;
}

.qos-good {
background-image : url('../custom/images/TwoBars.png'); 
background-repeat: no-repeat;
background-position: center;
}

.qos-fair {
background-image : url('../custom/images/OneBar.png'); 
background-repeat: no-repeat;
background-position: center;
}

.qos-poor {
background-image : url('../custom/images/NoBars.png'); 
background-repeat: no-repeat;
background-position: center;
}

Notice that we added a hyperlink in the code above, so clicking on the QoS description brings up a legend of the QoS ranges. You can download that file here: ConnectionQuality.html.