I'm trying to use SignalR to update a modal in my client while a zip folder is create on server side, I followed this tutorial : https://www.codeproject.com/Articles/1124691/SignalR-Progress-Bar-Simple-Example-Sending-Live-D
It works only sometimes but i cannot explain why i have this strange behavior : When it's not working the modal is updated only after my zip is sent to the client the progression go directly to the end. In debug mode i can see the calling of my function during my loop in server side but my client isn't aware of these calls except at end of my function.
There is the logs when it's not working :
SignalR.Transports.TransportHeartBeat Information: 0 : Connection 0ae92aec-a196-40df-b857-4c97fed7932d is New. SignalR.Transports.WebSocketTransport Verbose: 0 : Sending outgoing message. Connection id: 0ae92aec-a196-40df-b857-4c97fed7932d, transport: WebSocketTransport, message: {"C":"d-7952E959-B,0|C,0|D,1","S":1,"M":[]} SignalR.Transports.TransportHeartBeat Verbose: 0 : KeepAlive(0ae92aec-a196-40df-b857-4c97fed7932d) SignalR.Transports.WebSocketTransport Verbose: 0 : Sending outgoing message. Connection id: 0ae92aec-a196-40df-b857-4c97fed7932d, transport: WebSocketTransport, message: {"C":"d-7952E959-B,0|C,4|D,1","M":[{"H":"ProgressHub","M":"AddProgress","A":["Préparation en cours, merci de patienter...","1/4"]},{"H":"ProgressHub","M":"AddProgress","A":["Préparation en cours, merci de patienter...","2/4"]},{"H":"ProgressHub","M":"AddProgress","A":["Préparation en cours, merci de patienter...","3/4"]},{"H":"ProgressHub","M":"AddProgress","A":["Préparation en cours, merci de patienter...","4/4"]}]}
As you can see all the progression is sent in one websockettransport
Wherease when it's ok i have these :
SignalR.Transports.TransportHeartBeat Information: 0 : Connection 4ba31f7b-1b2d-481f-8692-74e2bdddb79c is New. SignalR.Transports.WebSocketTransport Verbose: 0 : Sending outgoing message. Connection id: 4ba31f7b-1b2d-481f-8692-74e2bdddb79c, transport: WebSocketTransport, message: {"C":"d-D358E1ED-B,0|E,0|F,1","S":1,"M":[]} SignalR.Transports.WebSocketTransport Verbose: 0 : Sending outgoing message. Connection id: 4ba31f7b-1b2d-481f-8692-74e2bdddb79c, transport: WebSocketTransport, message: {"C":"d-D358E1ED-B,0|E,1|F,1","M":[{"H":"ProgressHub","M":"addprogress","A":["Préparation en cours, merci de patienter...","1/50"]}]} SignalR.Transports.WebSocketTransport Verbose: 0 : Sending outgoing message. Connection id: 4ba31f7b-1b2d-481f-8692-74e2bdddb79c, transport: WebSocketTransport, message: {"C":"d-D358E1ED-B,0|E,2|F,1","M":[{"H":"ProgressHub","M":"addprogress","A":["Préparation en cours, merci de patienter...","2/50"]}]} SignalR.Transports.WebSocketTransport Verbose: 0 : Sending outgoing message. Connection id: 4ba31f7b-1b2d-481f-8692-74e2bdddb79c, transport: WebSocketTransport, message: {"C":"d-D358E1ED-B,0|E,3|F,1","M":[{"H":"ProgressHub","M":"addprogress","A":["Préparation en cours, merci de patienter...","3/50"]}]} SignalR.Transports.WebSocketTransport Verbose: 0 : Sending outgoing message. Connection id: 4ba31f7b-1b2d-481f-8692-74e2bdddb79c, transport: WebSocketTransport, message: {"C":"d-D358E1ED-B,0|E,4|F,1","M":[{"H":"ProgressHub","M":"addprogress","A":["Préparation en cours, merci de patienter...","4/50"]}]}
.......
One WebSocketTransport for each step of the progress is sent.
My Code :
$(function () {
var progress = $.connection.progressHub;
progress.client.addprogress = function (message, percentage) {
values = percentage.split('/');
left = values[0];
right = values[1];
if (left == right) {
ProgressBarModal("show", message + " " + percentage);
}else {
ProgressBarModal("show", message + " " + percentage);
}
$('#ProgressMessage').width(percentage + '%');
};
$.connection.hub.start().done(function () {
console.log("start hub");
var connectionId = $.connection.hub.id;
console.log("ConnectionID=" + connectionId);
});
});
public class ProgressHub : Hub
{
public static void SendProgress(string connectionId, string progressMessage, int progressCount, int totalItems)
{
var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
hubContext.Clients.Client(connectionId).AddProgress(progressMessage, progressCount + "/" + totalItems);
}
}
[assembly: OwinStartup(typeof(prodipmvc.Startup1))]
namespace prodipmvc
{
public class Startup1
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
MyController :
[HttpPost]
public ActionResult TelechargerPDF(string connectionId, List<string> selectedItems, string filigrane)
{
string sysFile = "";
//Contrôle paramètre obligatoire
if (selectedItems == null || selectedItems.Count <= 0)
{
Response.StatusCode = 599;
Response.StatusDescription = Resources.Erreurs.Archive_Telecharger_Non_Selectionner;
return Json(new { success = false, responseText = Resources.Erreurs.Archive_Telecharger_Non_Selectionner });
}
ProdipRoot ProdipR = (ProdipRoot)Session["ProdipRoot"];
try
{
//Initialisations
List<string> listeSysFilesPourLog = new List<string>(); //liste des sysfiles decrypté pour logger le telechargement
MemoryStream output = new MemoryStream(); //
int numero_ligne = 0;
selectedItems = selectedItems.Distinct().ToList();
string handle = Guid.NewGuid().ToString();
List<string> decryptedSysFiles = new List<string>();
List<string> PathOfFiles = new List<string>();
var hubContext = GlobalHost.ConnectionManager.GetHubContext<Models.ProgressHubs.Util.ProgressHub>();
foreach (string file in selectedItems)
{
numero_ligne++;
Models.ProgressHubs.Util.ProgressHub.SendProgress(connectionId, "Préparation en cours, merci de patienter...", numero_ligne, selectedItems.Count);
decryptedSysFiles.Add(sysFile);
PrArchive archiveParent = ProdipR.Archives.ArchivesList.Find(x => x.DbId == ProdipR.ProDip.archive_dbID);
PrDocument doc = new PrDocument(ProdipR, archiveParent, sysFile);
string cheminFichier = doc.GenerateNewFileName();
if(!string.IsNullOrEmpty(cheminFichier))
PathOfFiles.Add(cheminFichier); //on remplie la liste des chemins à Zipper
}
string cheminDossierSession = HttpContext.Server.MapPath("~/workspace/" + ProdipR.SessionUUID + "/") + DateTime.Now.ToString("dd-MM-yyyy_HH-mm-ss") + ".zip";
using (ZipFile zip = new ZipFile())
{
zip.AlternateEncodingUsage = ZipOption.AsNecessary;
zip.AddFiles(PathOfFiles, ""); //On zip la liste entière!
zip.ParallelDeflateThreshold = -1;
zip.Save(cheminDossierSession);
ProdipR.Histo.TelechargerPDF(ProdipR.CurrentUserUUID, handle, ProdipR.ProDip.archive_dbID, ProdipR.Archives.ArchivesList.Find(x => x.DbId == ProdipR.ProDip.archive_dbID).DbName, decryptedSysFiles);
}
TempData[handle] = cheminDossierSession;
return Json(new { success = true, fileGuid = handle });
}
catch(Exception ex)
{
//ERREUR : Historisation & Redirection
ProdipR.Histo.ErreurApplicativeImportante(ProdipR.CurrentUserUUID, ex.Message + " - " + ex.StackTrace, "Archive", "TelechargerPDF", "", sysFile, "");
Response.StatusCode = 599;
Response.StatusDescription = ex.Message;
return Json(new { success = false, responseText = ex.Message });
}
}
}
My function TelechargerPDF is an ajax call:
$.ajax({
url: '@Url.Action("TelechargerPDF", "Archive")',
type: 'POST',
data: { "connectionId": $.connection.hub.id, selectedItems: selectedFile, filigrane: MentionAppliquee },
dataType: 'json',
beforeSend: function () {
$("#overlay").show();
},
success: function (response) {
//On attend une sec car des fois le success est executé avant les derniers showprogress de la progressbar
ProgressBarModal("hide", "");
$("#overlay").hide();
window.location = "@Url.Action("DownloadPDF", "Archive")?fileGuid=" + response.fileGuid+"&fileName=@System.Web.HttpUtility.UrlEncode(Model.DbNamealias.Replace(" ","_").Replace("&","_"))";
},
error: function (jqXHR, textStatus, errorThrown) {
ProgressBarModal("hide", "");
if (jqXHR.status == 599) {
ShowErreurMessageClient(jqXHR.statusText);
}
else {
ShowErreurMessageClient("@Html.Raw(prodipmvc.Resources.Erreurs.Erreur_Innatendu)");
}
},
complete: function (resultat, statut) {
$("#overlay").hide();
}
});
I see nothing in the inspector when it's not working. I don't see any hub disconnection during the progression. If you have any suggestion ? Thanks for your help and time.