I am using SignalR 1.2.1 (because the project we are implementing in has .NET 4.0).
The process is basically:
- JS client starts hub connection, and starts by calling
BeginPolling
: BeginPolling
referencesReportProgress
/GetProgress
inRenewalImportProgress
.showProgress
displays the updated progress message to the clientimportDone
is another client method that stops the connection, shows "Done!", and re-enables the form fields.
The problem that I'm having is that if I try to start a second import, or even clicking a button that does a simple window.location
redirect (right after completion) I am delayed for about 5-10 seconds. Other users have reported delays of up to 30 seconds on other machines as well.
I have turned on client-side logging and also have a stateChanged
function for signalR and the connection says that it is closed, not sure what may be causing this delay/locking? Happens in both IE and Chrome.
var progressNotifier = $.connection.progressHub;
progressNotifier.client.showProgress = function (message) {
UpdateProgress(message);
};
progressNotifier.client.importDone = function () {
$.connection.hub.stop(); //stop hub connection
//delayed to show "Done!" temporarily
setTimeout(function () {
$('#message').hide();
$('input').prop('disabled', false); //enable input fields
$('#batchName').focus(); //give focus and clear fields
$('#batchName').val('');
$('#batchDescription').val('');
}, 1000);
};
$.connection.hub.start().done(function () {
$.ajax({
url: "Import/ImportXmlFile",
type: 'POST',
dataType: "json",
data: JSON.stringify(@Html.Raw(Json.Encode(Model))),
contentType: 'application/json;charset=utf-8',
});
progressNotifier.server.beginPolling("@Model.BATCHID");
});
function UpdateProgress(msg) {
$("#result").html(msg);
}
ProgressHub.cs:
public class ProgressHub : Hub
{
private readonly RenewalImportProgress _renewalImportProgress;
public ProgressHub() : this(RenewalImportProgress.Instance) { }
public ProgressHub(RenewalImportProgress renewalImportProgress)
{
_renewalImportProgress = renewalImportProgress;
}
public void BeginPolling(string batchId)
{
_renewalImportProgress.GetProgress(batchId);
}
}
RenewalImportProgress.cs:
public class RenewalImportProgress
{
private readonly static Lazy<RenewalImportProgress> _instance = new Lazy<RenewalImportProgress>(() => new RenewalImportProgress(GlobalHost.ConnectionManager.GetHubContext<ProgressHub>().Clients));
private readonly TimeSpan _updateInterval = TimeSpan.FromMilliseconds(1000);
private readonly Timer _timer;
private string _batchId;
private RenewalImportProgress(IHubConnectionContext clients)
{
Clients = clients;
_timer = new Timer(ReportProgress, null, _updateInterval, _updateInterval);
}
public static RenewalImportProgress Instance{ get { return _instance.Value; } }
private IHubConnectionContext Clients { get; set; }
private void ReportProgress(object state)
{
GetProgress(_batchId);
}
public void GetProgress(string batchId)
{
if (!string.IsNullOrEmpty(batchId)) _batchId = batchId;
Stats stats;
var message = "Preparing file...";
using (var _repository = new ImportRepository())
{
stats = _repository.GetImportStats(_batchId);
}
if (stats != null && stats.ProcessCount != 0)
{
var processedCount = stats.ProcessCount + stats.ErrorCount;
if (stats.BatchCount > processedCount)
{
message = "Processing... " + processedCount.ToString() + " of " + stats.BatchCount.ToString() + " completed.";
Clients.All.showProgress(message);
}
else if (stats.BatchCount == processedCount)
{
message = "Processing file... Done!";
Clients.All.showProgress(message);
Clients.All.importDone();
}
}
}
}