SignalR causing bad request 400 seen on the server - asp.net

We are having an issue with signalR. We have an auction site that runs on signalr for real time bidding. We fixed some issues with the browser and everything seemed to be working well. Then we installed new relic on our server and noticed that every minute we are getting http error code 400 on signalr connect, reconnect and abort. Here's a screenshot:
SignalR connect and reconnect are the most time consuming operations of the site according to new relic.
Here is SignalR backend code (We use sql server as signalr backplane):
public class SignalRHub : Hub
{
public void BroadCastMessage(String msg)
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<SignalRHub>();
hubContext.Clients.All.receiveMessage(msg);
}
}
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
string appString=string.Empty;
//Gets the connection string.
if (System.Configuration.ConfigurationSettings.AppSettings["SignaRScaleoutConn"] != null)
{
appString = System.Configuration.ConfigurationSettings.AppSettings["SignaRScaleoutConn"].ToString();
}
GlobalHost.DependencyResolver.UseSqlServer(appString);
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromMinutes(15); //I added this timeout, but it is not required.
app.MapSignalR();
}
}
The javascript client looks like this, it's lengthy, but most of it is jQuery to affect the DOM, I include it all in case something may be wrong inside it.
$(function () {
var chatProxy = $.connection.signalRHub;
$.connection.hub.start();
chatProxy.client.receiveMessage = function (msg) {
var all = $(".soon").map(function () {
var hiddenModelId = $("#hiddenListingId");
if (msg == hiddenModelId.val()) {
$.ajax({
async: "true",
url: "/Listing/AuctionRemainingTime",
type: "POST",
dataType: 'json',
data: '{ "listingID": "' + msg + '"}',
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data != null) {
SoonSettings.HasReloadedThisTick = false;
var element = document.getElementById(msg);
var obj = JSON.parse(data)
// For Clock Counter End Date Time Interval
// Adds 2 minutes to the soon clock when bid is close to finishing.
var hdID = "hdn" + obj.ListingId;
var hdValue = $("#" + hdID);
if (obj.EndDate != hdValue.val()) {
SoonSettings.HasUpdated = false; //Allows clock to change color once it gets under two minutes.
$('#' + hdID).val(obj.EndDate);
Soon.destroy(element);
Soon.create(element, { //Recreates clock with the before 2 minute tick event.
'due': 'in ' + obj.Seconds + ' seconds',
'layout':'group label-uppercase',
'visual':'ring cap-round progressgradient-00fff6_075fff ring-width-custom gap-0',
'face':'text',
'eventTick': 'tick'
});
}
var highbid = obj.HighBidderURL;
// For Date Ends Info.
var ListingEndDate = $("#tdAuctionListingEndDate");
if (obj.EndDate != ListingEndDate.val()) {
$('#' + hdID).val(obj.EndDate);
ListingEndDate.text(obj.EndDate + " Eastern");
ListingEndDate.effect("pulsate", { times: 5 }, 5000);
}
else
{
$(".Bidding_Current_Price").stop(true, true); ///Removes the pulsating effect.
$(".Bidding_Current_Price").removeAttr("style"); //Removes unnecessary attribute from HTML.
}
//Bid div notification.
if (obj.AcceptedActionCount.replace(/[^:]+:*/, "") > 0) {
if (obj.Disposition != '' && obj.Disposition != null) {
if (obj.Disposition == "Neutral") {
$("#spanNeutralBid").show();
$("#divOutbidNotification").hide();
$("#spanPositiveBid").hide();
$("#divProxyBidNotification").hide();
}
else if (obj.Disposition == "Positive") {
$("#spanPositiveBid").show();
$("#divOutbidNotification").hide();
$("#spanNeutralBid").hide();
$("#divProxyBidNotification").hide();
}
else if (obj.Disposition == "Negative") {
$("#divOutbidNotification").show();
$("#spanNeutralBid").hide();
$("#spanPositiveBid").hide();
$("#divProxyBidNotification").hide();
}
else {
$("#divOutbidNotification").hide();
$("#spanNeutralBid").hide();
$("#divProxyBidNotification").hide();
$("#spanPositiveBid").hide();
}
}
}
// For Highlight Current Price when it is Updated
var hdCurrentPrice = $("#hdnCurrentPrice");
if (obj.CurrentPrice != hdCurrentPrice.val()) {
$(".Bidding_Current_Price").text(obj.CurrentPrice);
$(".Bidding_Current_Price").effect("pulsate", { times: 5 }, 5000);
$("#hdnCurrentPrice").val(obj.CurrentPrice);
}
else {
$(".Bidding_Current_Price").stop(true, true);
$(".Bidding_Current_Price").removeAttr("style");
}
// For ReservePrice Status
$("#spanReservePriceStatus").html(obj.ReservePriceStatus);
$("#smallReservePriceStatus").html(obj.ReservePriceStatus);
// For Bid Count
var spanBidCounter = $("#spanBidCount");
$(spanBidCounter).text(obj.AcceptedActionCount);
var stringAppend = "<tr id='trhHighBidder'><td><strong>HighBidder</strong></td>";
stringAppend += "<td>";
if (obj.isAdmin == true) {
stringAppend += "<a id='anchorHighBid' href=" + obj.HighBidderURL + ">";
stringAppend += "<span id='spanHighBidder'>" + obj.CurrentListingActionUserName + "</span>"
stringAppend += "</a>";
}
else {
stringAppend += "<span id='spanHighBidderAnonymous'>" + obj.CurrentListingActionUserName + "</span>";
}
stringAppend += "</td></tr>";
if (obj.AcceptedActionCount.replace(/[^:]+:*/, "") > 0) {
if ($("#tblAuctionDetail").find("#rowHighBidder").length > 0) {
if ($("#tblAuctionDetail").find("#trhHighBidder").length > 0) {
$("#trhHighBidder").remove();
}
}
else {
//add tr to table
if (!$("#tblAuctionDetail").find("#trhHighBidder").length > 0) {
$('#tblAuctionDetail > tbody > tr:eq(6)').after(stringAppend);
}
}
}
// For High Bidder
if (obj.isAdmin) {
var anchorElement = $("#anchorHighBid");
$(anchorElement).attr("href", obj.HighBidderURL);
var spanHighBidder = $("#spanHighBidder");
$(spanHighBidder).text(obj.CurrentListingActionUserName);
}
else {
var spanAdminHighBid = $("#spanHighBidderAnonymous");
$(spanAdminHighBid).text(obj.CurrentListingActionUserName)
}
}
},
error: function (xhr, textStatus, errorThrown) {
}
});
}
});
};
});
Is there anything wrong with the client or the server signalr code that may need to be changed to avoid these errors happening so often? The 400 code has the tendency of showing up almost every minute. I am very new to signalR and know very little of how to make effective code with it.
The real time bidding in the site does work, it's just to find a way to avoid these constant errors. Any help explaining anything of how signalR works is appreciated.
Thanks,

I'd give a try changing the transportation method of SignalR: http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client#transport
and check if problem persists.
If possible to get UserAgent from Bad Request log, try to narrow down which browsers get 400 error. I think, maybe, some browsers are not connecting with correct transport method.

Related

<a onclick"sth" .. cause IE11 warn and prompt for adding about:blank as Trusted Site

I have jqgrid on asp .NET web page.
When page is loaded and grid loads its data, after it receives json, before data is shown on grid, I get error message from IE:
Internet Explorer 11.0.9600.17728
It wants me to add about:blank to Trusted Sites.
When i click "close" rows appear.
Row`s html is as follows:
<a onclick="
OpenWindow('/13_1/Workflow.TasksWebPresUnit/TaskDetails/Index/?
taskDn=WFL///70000/.321360&isModal=True&
returnUrl=/13_1/Workflow.TasksWebPresUnit&
userId=5&
componentsToSet=test*testc', 'Details', '90%', '0', false, 'ยก',true);"
href="#">P01.07 Verification
</a>
No matter what I put in onclick, can be "blahblah", same with href, can be "foobar",
<a onclick="
abcd"
href="xyz">P01.07 Verification
</a>
i get that error window.
But, when I construct row's html that it not contain "onclick=sth", then i do not get this error.
Is there any way to stop IE from warning user or maybe I`m doing somethiong wrong?
Any help / clarification appreciated.
p.s. If i add about:blank to trusted sites, the problem is gone, but i don`t understand fully if this is secure solution.
Update 1: script
function OpenWindow(url, title, width, height, checkValue, multiSepar, showCloseButton) {
var progressIndImg = GLOBAL_CSS_PATH + '/Technology/modal/images/waiting.gif';
if (checkValue) {
var queryVals = parseQueryString(url);
var relatedComp = queryVals['componentToFill'];
var relatedVal = document.getElementById(relatedComp);
if (relatedVal.value != null && relatedVal.value != '') {
var win = dhtmlmodal.open('ModalBox', 'iframe', url, title, 'width=' + width + ', height=' + height + ',center=1,resize=1,scrolling=1', '', progressIndImg, showCloseButton);
win.onclose = function () {
return true;
}
}
} else {
var win = dhtmlmodal.open('ModalBox', 'iframe', url, title, 'width=' + width + ', height=' + height + ',center=1,resize=1,scrolling=1', '', progressIndImg, showCloseButton);
win.onclose = function () {
return true;
}
}
// } else {
// setInterval(checkForMessages, 200);
// }
// var ie7 = (navigator.appVersion.indexOf('MSIE 7.') == -1) ? false : true;
// if (ie7 != true) {
var onmessage = function (e) {
try {
var objects = JSON.parse(e.data);
if (window.addEventListener) {
window.removeEventListener('message', onmessage, false);
}
else if (window.attachEvent) {
window.detachEvent('onmessage', onmessage);
}
if (objects['methodName'] != null)
window[objects['methodName']](objects);
else
FillData(objects, true, multiSepar);
var close = objects['close'];
if (close == 'true') {
win.hide();
win.close();
}
}
catch (err) {
if (console)
console.error(err);
}
};
if (window.addEventListener) {
window.addEventListener('message', onmessage, false);
} else if (window.attachEvent) {
window.attachEvent('onmessage', onmessage);
}

Azure Media Player Silverlight fallback not working

I have used the azure media player with my project, it will play multiple adaptive bit rate streamed videos in an asp.net page, the best part is, it is working superb in html5 and flash but it will get stuck at spinner image in silverlight fallback.
Below is the code I have used.
I have also tried to get errors but it is not hitting the event listener code added for errors, but the play and pause events are working fine where flash and html5 is used, but silverlight fallback is not working at all.
<link href="https://amp.azure.net/libs/amp/1.3.0/skins/amp-default/azuremediaplayer.min.css" rel="stylesheet">
<script src="https://amp.azure.net/libs/amp/1.3.0/azuremediaplayer.min.js"></script>
<div class="marginBlock">
<h3>
<asp:Label ID="lblTitle" runat="server"><%=Title.ToString()%></asp:Label>
</h3>
<video id="<%=mediaPlayerID %>" class="azuremediaplayer amp-default-skin amp-big-play-centered">
<p class="amp-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML 5 video.
</p>
</video>
</div>
<p>
<asp:Label ID="lblDescription" runat="server"><%=Description.ToString()%>
</asp:Label>
</p>
<script>
$(document).ready(function () {
var playOptions = {
"nativeControlsForTouch": false,
techOrder: ['azureHtml5JS', 'flashSS', 'silverlightSS', 'html5'],
autoplay: false,
controls: true,
width: '100%',
height: '400',
logo: { enabled: false },
poster: "<%=ImageSelector%>"
}
var azurePlayer = amp('<%=mediaPlayerID%>', playOptions);
azurePlayer.src([{
src: "<%=VideoURL%>",
type: 'application/vnd.ms-sstr+xml'
}]);
azurePlayer.addEventListener("error", function () {
var errorDetails = azurePlayer.error();
var code = errorDetails.code;
var message = errorDetails.message;
alert(errorDetails + ' ' + code + " " + message);
if (azurePlayer.error().code & amp.errorCode.abortedErrStart) {
console.log("abortedErrStart");
}
else if (azurePlayer.error().code & amp.errorCode.networkErrStart) {
// MEDIA_ERR_NETWORK errors
console.log("networkErrStart");
}
else if (azurePlayer.error().code & amp.errorCode.decodeErrStart) {
// MEDIA_ERR_DECODE errors
console.log("decodeErrStart");
}
else if (azurePlayer.error().code & amp.errorCode.srcErrStart) {
// MEDIA_ERR_SRC_NOT_SUPPORTED errors
console.log("srcErrStart");
}
else if (azurePlayer.error().code & amp.errorCode.encryptErrStart) {
// MEDIA_ERR_ENCRYPTED errors
console.log("encryptErrStart");
}
else if (azurePlayer.error().code & amp.errorCode.srcPlayerMismatchStart) {
// SRC_PLAYER_MISMATCH errors
console.log("srcPlayerMismatchStart");
}
else {
// unknown errors
console.log("unknown");
}
});
azurePlayer.addEventListener('play', function () {
console.log('play');
});
azurePlayer.addEventListener('pause', function () {
console.log('pause');
});
});
Updated
Noticed I am getting following error for IE < 11.
Also I disabled the flash in firefox and removed the silverlight from techOrder, then it should hit the error event listener, it is not hitting.
This is also important for me to handle the analytics for error.
Play and Pause event listener are working fine.
Update 8/28/2015:
Fixed the JS error, it is because of multiple call to cdn of azure mentioned in link above, moved the code in master page and load it only once, browser like chrome handles duplicity of code easily but not IE.
After all the research I am lost why it is not working.
So added the following JS that will check for Silverlight and Flash and gracefully handle the error and update our analytics as well.
function getBrowserInformation() {
var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
return { name: 'IE ', version: (tem[1] || '') };
}
if (M[1] === 'Chrome') {
tem = ua.match(/\bOPR\/(\d+)/)
if (tem != null) { return { name: 'Opera', version: tem[1] }; }
}
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); }
return {
name: M[0],
version: M[1]
};};
function checkForAzureErrors() {
function isSilverlightInstalled() {
var isSilverlightInstalled = false;
try {
//check on IE
try {
var slControl = new ActiveXObject('AgControl.AgControl');
isSilverlightInstalled = true;
}
catch (e) {
//either not installed or not IE. Check Firefox/Safari
if (navigator.plugins["Silverlight Plug-In"]) {
isSilverlightInstalled = true;
}
}
}
catch (e) {
console.log(e);
}
return isSilverlightInstalled;
}
function isFlashInstalled() {
try {
return Boolean(new ActiveXObject('ShockwaveFlash.ShockwaveFlash'));
} catch (exception) {
return ('undefined' != typeof navigator.mimeTypes['application/x-shockwave-flash']);
}
}
function addErrorMessage() {
$($("#mediaPlayer.marginBlock").find('h3')).text('Media is not supported on this browser or device.');
$($("#mediaPlayer.marginBlock").find('video')).css('display', 'none');
$($("#mediaPlayer.marginBlock").find('p')).css('display', 'none');
$('.azuremediaplayer').css('display', 'none');
ga("send", "event", "Videos", "error",
getBrowserInformation().name + getBrowserInformation().version +
": is silverlight Installed " + isSilverlightInstalled() +
" and is Flash Installed " + isFlashInstalled());
}
function checkBrowser() {
if ((getBrowserInformation().name === 'MSIE' || getBrowserInformation().name === 'IE')) {
if (getBrowserInformation().version < 11) {
addErrorMessage();
}
} else if (getBrowserInformation().name === 'Firefox') {
addErrorMessage();
}
}
if ((getBrowserInformation().name === 'MSIE' || getBrowserInformation().name === 'IE')) {
if (getBrowserInformation().version < 9) { addErrorMessage() }
}
for (var key in amp.players) {
if (amp.players.hasOwnProperty(key)) {
if (isSilverlightInstalled()) {
if (!amp.players[key].isReady_) {
checkBrowser();
}
} else if (!isFlashInstalled()) {
checkBrowser();
}
}
}}
This function is called after 5 second of page load in document.ready function, giving it enough time to load and make the isReady_boolean true.
SetTimeout(function () { checkForAzureErrors(); }, 5000);
Still I am waiting for some angel to resolve this issue.
Updates: Partially Fixed
Need to add the xap refrences like older version, it will play silverlight but there is a catch, it will only work if you have one video per page.
<script>
amp.options.flashSS.swf = "http://amp.azure.net/libs/amp/1.3.0/techs/StrobeMediaPlayback.2.0.swf"
amp.options.flashSS.plugin = "http://amp.azure.net/libs/amp/1.3.0/techs/MSAdaptiveStreamingPlugin-osmf2.0.swf"
amp.options.silverlightSS.xap = "http://amp.azure.net/libs/amp/1.3.0/techs/SmoothStreamingPlayer.xap"
</script>
Fixed
As per comments from Amit Rajput
#Parshii Currently, as per the documentation, Azure Media Player doesn't support multi-instance playback. While it may work on some techs, it is not a tested scenario at this time. Please feel free to add it to the UserVoice forum (http://aka.ms/ampuservoice).
As per my testing it is working in html5 and flash but not Silverlight, for silverlight support we can try using iframes as per comments from rnrneverdies
Single Instance Media Player is working in all techs.
#Parshii Currently, as per the documentation, Azure Media Player doesn't support multi-instance playback. While it may work on some techs, it is not a tested scenario at this time. Please feel free to add it to the UserVoice forum (http://aka.ms/ampuservoice).
This may be not a complete answer, but could help you.
I made the following plugin for the Azure Media Player 1.3.0 which logs all the activity performed by the user and also the errors.
Set up it as:
var mylogFunction = function(data) { console.log(data); };
var options = {
techOrder: ["azureHtml5JS", "flashSS", "silverlightSS", "html5"],
nativeControlsForTouch: false,
loop: false,
logo: { enabled: false },
heuristicProfile: "Quick Start", //"High Quality", // could be "Quick Start"
customPlayerSettings: {
customHeuristicSettings: {
preRollInSec: 4,
windowSizeHeuristics: true
}
},
plugins: {
DebugLog: {
logFunction: mylogFunction
}
}
};
var amPlayer = amp("yourvideotagid", options);
Plugin Code:
var amp;
(function (amp) {
amp.plugin('DebugLog', DebugLog);
function DebugLog(options) {
var player = this;
var log = function (data) { console.log("Azure Media Player Log", data); }
if (options) {
if (options['logFunction']) {
log = options['logFunction'];
}
}
init();
function init() {
player.ready(handleReady);
player.addEventListener(amp.eventName.error, handleError);
}
function handleReady() {
player.addEventListener(amp.eventName.loadedmetadata, handleLoadedMetaData);
var data = {
ampVersion: "1.3.0",
appName: options['appName'],
userAgent: navigator.userAgent,
options: {
autoplay: player.options().autoplay,
heuristicProfile: player.options().heuristicProfile,
techOrder: JSON.stringify(player.options().techOrder)
}
};
logData("InstanceCreated", 1, data);
}
function handleError() {
var err = player.error();
var data = {
sessionId: player.currentSrc(),
currentTime: player.currentTime(),
code: "0x" + err.code.toString(16),
message: err.message
};
logData("Error", 0, data);
}
function handleLoadedMetaData() {
player.addEventListener(amp.eventName.playbackbitratechanged, handlePlaybackBitrateChanged);
player.addEventListener(amp.eventName.playing, handlePlaying);
player.addEventListener(amp.eventName.seeking, handleSeeking);
player.addEventListener(amp.eventName.pause, handlePaused);
player.addEventListener(amp.eventName.waiting, handleWaiting);
player.addEventListener(amp.eventName.ended, handleEnded);
if (player.audioBufferData()) {
player.audioBufferData().addEventListener(amp.bufferDataEventName.downloadfailed, function () {
var data = {
sessionId: player.currentSrc(),
currentTime: player.currentTime(),
bufferLevel: player.audioBufferData().bufferLevel,
url: player.audioBufferData().downloadFailed.mediaDownload.url,
code: "0x" + player.audioBufferData().downloadFailed.code.toString(16),
message: player.audioBufferData().downloadFailed
};
logData("DownloadFailed", 0, data);
});
}
if (player.videoBufferData()) {
player.videoBufferData().addEventListener(amp.bufferDataEventName.downloadfailed, function () {
var data = {
sessionId: player.currentSrc(),
currentTime: player.currentTime(),
bufferLevel: player.videoBufferData().bufferLevel,
url: player.videoBufferData().downloadFailed.mediaDownload.url,
code: "0x" + player.videoBufferData().downloadFailed.code.toString(16),
message: player.videoBufferData().downloadFailed
};
logData("DownloadFailed", 0, data);
});
}
var data = {
sessionId: player.currentSrc(),
isLive: player.isLive(),
duration: player.duration(),
tech: player.currentTechName(),
protection: ((player.currentProtectionInfo() && player.currentProtectionInfo()[0]) ? player.currentProtectionInfo()[0].type : "clear")
};
logData("PresentationInfo", 1, data);
}
function handlePlaybackBitrateChanged(event) {
logData("BitrateChanged", 1, eventData(event));
}
function handleWaiting(event) {
logData("Waiting", 0, eventData(event));
}
function handlePlaying(event) {
logData("Playing", 1, eventData(event));
}
function handleSeeking(event) {
logData("Seeking", 1, eventData(event));
}
function handlePaused(event) {
logData("Paused", 1, eventData(event));
}
function handleEnded(event) {
logData("Ended", 1, eventData(event));
}
function logData(eventId, level, data) {
var eventLog = {
eventId: eventId,
level: level,
data: data
};
log(eventLog);
}
function eventData(event) {
return {
sessionId: player.currentSrc(),
currentTime: player.currentTime(),
isLive: player.isLive(),
event: event.type,
presentationTimeInSec: event.presentationTimeInSec,
message: event.message ? event.message : ""
};
}
}
})(amp || (amp = {}));

Switch to iframe with phantom.js

I would like to switch to an iframe using pure phantom.js code
Here is my first attempt
var page = new WebPage();
var url = 'http://www.theurltofectch'
page.open(url, function (status) {
if ('success' !== status) {
console.log("Error");
} else {
page.switchToFrame("thenameoftheiframe");
console.log(page.content);
phantom.exit();
}
});
It produces only the source code of the main page. Any idea ?
Notice that the iframe domain is different from the main page domain.
Please give this a try I believe it may be an async issues meaning the iframe is not present when trying to access it. I received the below snippet from another post.
var page = require('webpage').create(),
testindex = 0,
loadInProgress = false;
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onLoadStarted = function() {
loadInProgress = true;
console.log("load started");
};
page.onLoadFinished = function() {
loadInProgress = false;
console.log("load finished");
};
/*
page.onNavigationRequested = function(url, type, willNavigate, main) {
console.log('Trying to navigate to: ' + url);
console.log('Caused by: ' + type);
console.log('Will actually navigate: ' + willNavigate);
console.log('Sent from the page\'s main frame: ' + main);
};
*/
/*
The steps array represents a finite set of steps in order to perform the unit test
*/
var steps = [
function() {
//Load Login Page
page.open("https://www.yourpage.com");
},
function() {
//access your iframe here
page.evaluate(function() {
});
},
function() {
//any other step you want
page.evaluate(function() {
});
},
function() {
// Output content of page to stdout after form has been submitted
page.evaluate(function() {
//console.log(document.querySelectorAll('html')[0].outerHTML);
});
//render a test image to see if login passed
page.render('test.png');
}
];
interval = setInterval(function() {
if (!loadInProgress && typeof steps[testindex] === "function") {
console.log("step " + (testindex + 1));
steps[testindex]();
testindex++;
}
if (typeof steps[testindex] !== "function") {
console.log("test complete!");
phantom.exit();
}
}, 50);
replace
console.log(page.content);
with
console.log(page.frameContent);
Should return the contents of the frame phantomjs switched to.
If the iframe is from another domain you may need to add the --web-security=no option like this:
phantomjs --web-security=no myscript.js
As an additional information, what xMythicx said could be true. Some iframes are rendered via Javascript after page finishes loading. If the iframe contents are empty, then you will need to wait for all resources to finish loading, before you start grabbing stuff from the page. But this is another issue, if you need an answer on this, I suggest you ask a new question about it, and I will answer there.
Had the same problem for iframes and
phantomjs --web-security=no
helped in my case :]

Real time data and retrieval plotting

So my question is as follows: I'm working on a mobile application that takes data from a vital sign sensor and sends to a telehealth server, so that a physician is able to retrieve the data from the server in real time as a plotted curve.
As I have a very weak background on this, my question is of two parts: a) how do I retrieve the data from the server in real time and b) can I use HTML5 libs or anything similar like HighCharts or Meteor charts or ZingCharts to have them plotted or is it impossible? Please be very specific as again I have a weak background on this :)
In ZingChart, you can do this in two ways:
Method 1 - Via Websockets - EX: http://www.zingchart.com/dataweek/presentation/feed.html
The websocket transport is part of the refresh/feed section, its attribute can be found here: Graph >> Refresh section of the ZingChart JSON docs. In addition, a server socket component is required and it has to follow some standard protocol in order to allow connectivity and transport with the client socket.
To get specific:
###############################
# NodeJS code
###############################
#!/usr/bin/env node
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
response.writeHead(404);
response.end();
});
server.listen(8888, function() {
console.log((new Date()) + ' Server is listening on port 8888');
});
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
function originIsAllowed(origin) {
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var type = '',
method = '',
status = 0;
var connection = request.accept('zingchart', request.origin);
connection.on('message', function(message) {
function startFeed() {
console.log('start feed');
status = 1;
if (method == 'push') {
sendFeedData();
}
}
function stopFeed() {
console.log('stop feed');
status = 0;
}
function sendFeedData() {
if (method == 'push') {
var ts = (new Date()).getTime();
var data = {
"scale-x": ts,
"plot0": [ts, parseInt(10 + 100 * Math.random(), 10)]
};
console.log('sending feed data (push)');
connection.sendUTF(JSON.stringify(data));
if (status == 1) {
iFeedTick = setTimeout(sendFeedData, 500);
}
} else if (method == 'pull') {
var data = [];
var ts = (new Date()).getTime();
for (var i = -5; i <= 0; i++) {
data.push({
"scale-x": ts + i * 500,
"plot0": [ts + i * 500, parseInt(10 + 100 * Math.random(), 10)]
});
}
console.log('sending feed data (pull)');
connection.sendUTF(JSON.stringify(data));
}
}
function sendFullData() {
var data = {
type: "bar",
series: [{
values: [
[(new Date()).getTime(), parseInt(10 + 100 * Math.random(), 10)]
]
}]
};
console.log('sending full data');
connection.sendUTF(JSON.stringify(data));
if (status == 1) {
if (method == 'push') {
setTimeout(sendFullData, 2000);
}
}
}
if (message.type === 'utf8') {
console.log('************************ ' + message.utf8Data);
switch (message.utf8Data) {
case 'zingchart.full':
type = 'full';
break;
case 'zingchart.feed':
type = 'feed';
break;
case 'zingchart.push':
method = 'push';
break;
case 'zingchart.pull':
method = 'pull';
break;
case 'zingchart.startfeed':
startFeed();
break;
case 'zingchart.stopfeed':
stopFeed();
break;
case 'zingchart.getdata':
status = 1;
if (type == 'full') {
sendFullData();
} else if (type == 'feed') {
sendFeedData();
}
break;
}
}
});
connection.on('close', function(reasonCode, description) {
status = 0;
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
###############################################
# Sample JSON settings for socket transport
###############################################
refresh: {
type: "feed",
transport: "websockets",
url: "ws://198.101.197.138:8888/",
method: "push",
maxTicks: 120,
resetTimeout: 2400
}
or
refresh: {
type: "feed",
transport: "websockets",
url: "ws://198.101.197.138:8888/",
method: "pull",
interval: 3000,
maxTicks: 120,
resetTimeout: 2400
}
Method 2 - Via API - EX: http://www.zingchart.com/dataweek/presentation/api.html
In the case you described, this would involve setting intervals of time at which you would like to retrieve data from your server, and then pass that data via the API. Check out the "Feed" section in API-Methods section of the ZingChart docs.

Uploading to Azure

I'm having an issue trying to directly upload a file to azure blob storage. I am using ajax calls to send post requests to an ashx handler to upload a blob in chunks. The issue I am running into is the handler isn't receiving the filechunk being sent from the ajax post.
I can see the page is receiving the post correctly from looking at the request in firebug,
-----------------------------265001916915724 Content-Disposition: form-data; >name="Slice"; filename="blob" Content-Type: application/octet-stream
I noticed the input stream on the handler has the filechunk, including additional bytes from the request. I tryed to read only the filechunk's size from the inputstream, however this resulted in an corrupt file.
I got the inspiration from http://code.msdn.microsoft.com/windowsazure/Silverlight-Azure-Blob-3b773e26 , I simply converted it from MVC3 to using standard aspx.
Here is the call using ajax to send the file chunk to the aspx page,
var sendFile = function (blockLength) {
var start = 0,
end = Math.min(blockLength, uploader.file.size),
incrimentalIdentifier = 1,
retryCount = 0,
sendNextChunk, fileChunk;
uploader.displayStatusMessage();
sendNextChunk = function () {
fileChunk = new FormData();
uploader.renderProgress(incrimentalIdentifier);
if (uploader.file.slice) {
fileChunk.append('Slice', uploader.file.slice(start, end));
}
else if (uploader.file.webkitSlice) {
fileChunk.append('Slice', uploader.file.webkitSlice(start, end));
}
else if (uploader.file.mozSlice) {
fileChunk.append('Slice', uploader.file.mozSlice(start, end));
}
else {
uploader.displayLabel(operationType.UNSUPPORTED_BROWSER);
return;
}
var testcode = 'http://localhost:56307/handler1.ashx?create=0&blockid=' + incrimentalIdentifier + '&filename=' + uploader.file.name + '&totalBlocks=' + uploader.totalBlocks;
jqxhr = $.ajax({
async: true,
url: testcode,
data: fileChunk,
contentType: false,
processData:false,
dataType: 'text json',
type: 'POST',
error: function (request, error) {
if (error !== 'abort' && retryCount < maxRetries) {
++retryCount;
setTimeout(sendNextChunk, retryAfterSeconds * 1000);
}
if (error === 'abort') {
uploader.displayLabel(operationType.CANCELLED);
uploader.resetControls();
uploader = null;
}
else {
if (retryCount === maxRetries) {
uploader.uploadError(request.responseText);
uploader.resetControls();
uploader = null;
}
else {
uploader.displayLabel(operationType.RESUME_UPLOAD);
}
}
return;
},
success: function (notice) {
if (notice.error || notice.isLastBlock) {
uploader.renderProgress(uploader.totalBlocks + 1);
uploader.displayStatusMessage(notice.message);
uploader.resetControls();
uploader = null;
return;
}
++incrimentalIdentifier;
start = (incrimentalIdentifier - 1) * blockLength;
end = Math.min(incrimentalIdentifier * blockLength, uploader.file.size);
retryCount = 0;
sendNextChunk();
}
});
};
Thanks so much for anything that can help me out.
is it ASPX on purpose? in http://localhost:56307/handler1.ashx?create=0&blockid?
Turns out on my webform, the input file tag was missing the enctype="multipart/form-data" attribute.

Resources