locked
Using SignalR just for just a user's session RRS feed

  • Question

  • User1256154619 posted

    I have a progress bar logic that implements SignalR on a page that processes uploaded file. It works properly and produces correct progress.

    However, it produces progress bar for ALL users, not just for the user that uploaded the file. In other words, one user uploads the file, but that progress for that file upload shows even on screens of other user/sessions that conducted no action on their ends

    I did come up with a workaround, where I send a user id with the SignalR progress call/signal and compare it with the user id stored in a hidden field on aspx. If they don't match, I don't produce the progress bar. However, this fix seems to be like a dirty workaround.

    Is there a more efficient way to ensure the SignalR to work only within one session?

    Just in case here is my code

    hubContext.Clients.All.AddProgress("Currently processing: ", new System.IO.FileInfo(attachment.FileName).Name, "0",
                                Context.User.Identity.Name, pageName);

    Here is my JavaScript

    $(function () {
        // Reference the auto-generated proxy for the hub.
        var progress = $.connection.progressHub;
        console.log(progress);
        var hfUserAccount = document.getElementById("<%=hfUserAccount.ClientID %>");
        // Create a function that the hub can call back to display messages.
        progress.client.AddProgress = function (fileName, message, percentage, userAccount, pageName) {
    
            if (userAccount === hfUserAccount.value && pageName === "CheckEFile.aspx") {
    
                ProgressBarModal("show", fileName + " " + message);
                document.getElementById("divProgress").style.display = "block";
                document.getElementById("divUpload").style.display = "block";
                document.getElementById("divProgress").style.width = percentage + "%";
                document.getElementById("lblPercentage").innerHTML = parseInt(percentage) + "%";
                $("#processingStatus").html("Please Wait. Checking files...");
                $('#ProgressMessage').width(percentage);
                if (percentage === "100%") {
                    ProgressBarModal();
                }
            }
        };
    
        $.connection.hub.start().done(function () {
            var connectionId = $.connection.hub.id;
            console.log(connectionId);
        });
    
    });

    Here is my hub

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    
    namespace IAACCESS.SignalR
    {
        public class ProgressHub : Hub
        {
            static ProgressHub()
            {
    
            }
        }
    }
    Tuesday, July 16, 2019 1:55 PM

Answers

  • User1256154619 posted

    Found a solution, in my aspx I have

            $.connection.hub.start().done(function () {
                var connectionId = $.connection.hub.id;
                console.log(connectionId);
                $('#<%=hfConnectionId.ClientID %>').val(connectionId);
            });

    where I set the connection ID to a hidden field

    <asp:HiddenField id="hfConnectionId" runat="server" />

    And in code-behind I now have

    hubContext.Clients.Client(hfConnectionId.Value).AddProgress("Currently processing: ", fn4, currentProgress, Context.User.Identity.Name, pageName);
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, July 24, 2019 5:16 PM

All replies

  • User283571144 posted

    Hi mpodolski,

    As far as I know, Signlar could send the response to specific user. You could try to use below codes to get the user connection ID. 

    string connectionID = Context.ConnectionId;
    

    Then you could send  response to that client id.

      public void Send ( string name , string message , string connID )
      {
            Clients.Client(connID).broadcastMessage(name , message);
      }

    Best Regards,

    Brando

    Wednesday, July 17, 2019 5:22 AM
  • User1256154619 posted

    Brando, thank you very much for your response

    Below I specified how I get the context, however, unfortunately, neither hubContext nor other properties below give me Connection ID. Is there a specific way to get the Connection ID for SignalR in WebForms?

    var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();

    Wednesday, July 17, 2019 1:44 PM
  • User283571144 posted

    Hi mpodolski,

    As far as I know, when a client invokes a function on the server side you can retrieve their connection ID via Context.ConnectionId. You could get it in the hub method.

    Like below:

            public async Task SendMessage(string userName, string userMessage)
            {
                var re = Context.ConnectionId;
                await Clients.All.SendAsync("Receive Message", userName, userMessage);
            }

    Best Regards,

    Brando

    Thursday, July 18, 2019 1:43 AM
  • User1256154619 posted

    Brando, thank you again for your reply. The 'Context' isn't available anywhere in the 'Microsoft.AspNet.SignalR' namespace. Could you please let me know what namespace on your end the 'Context' exists in?

    Thank you once again for your help!

    Thursday, July 18, 2019 3:07 PM
  • User283571144 posted

    Hi mpodolski,

    You should use context inside the hub class.  Microsoft.AspNet.SignalR.Hubs.HubBase.Context.

    Details codes as below:

    You could get it insider the hub methid and store it  in the server storage and use it on other side.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Microsoft.AspNet.SignalR;
    
    namespace AspNetNormalIssue.hub
    {
        public class MyHub1 : Hub
        {
            public void Hello()
            {
                var re = Context.ConnectionId;
                Clients.All.hello();
            }
        }
    }

    Best Regards,

    Brando

    Friday, July 19, 2019 1:48 AM
  • User1256154619 posted

    Found a solution, in my aspx I have

            $.connection.hub.start().done(function () {
                var connectionId = $.connection.hub.id;
                console.log(connectionId);
                $('#<%=hfConnectionId.ClientID %>').val(connectionId);
            });

    where I set the connection ID to a hidden field

    <asp:HiddenField id="hfConnectionId" runat="server" />

    And in code-behind I now have

    hubContext.Clients.Client(hfConnectionId.Value).AddProgress("Currently processing: ", fn4, currentProgress, Context.User.Identity.Name, pageName);
    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, July 24, 2019 5:16 PM