【问题标题】:Using SignalR just for just a user's session仅将 SignalR 用于用户会话
【发布时间】:2019-07-25 01:14:25
【问题描述】:

我有一个在处理上传文件的页面上实现 SignalR 的进度条逻辑。它可以正常工作并产生正确的进度。

但是,它会为所有用户生成进度条,而不仅仅是上传文件的用户。换句话说,一个用户上传了文件,但该文件上传的进度甚至显示在其他用户/会话的屏幕上,这些用户/会话没有对其进行任何操作

我确实想出了一个解决方法,我发送一个带有 SignalR 进度调用/信号的用户 ID,并将其与存储在 aspx 上的隐藏字段中的用户 ID 进行比较。如果它们不匹配,我不会生成进度条。但是,此修复程序似乎是一种肮脏的解决方法。

是否有更有效的方法来确保 SignalR 仅在一个会话中工作?

以防万一这是我的代码

protected void btnSubmit_Click(object sender, EventArgs e)
{
    HttpFileCollection attachments = null;
    try
    {

        lblMessage.Text = string.Empty;
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();

        hubContext.Clients.All.AddProgress("Upload has been initiated: ", string.Empty, "0", 
            Context.User.Identity.Name, pageName);
        if (fileupload1.HasFile)
        {
            attachments = Request.Files;
            if (attachments.Count > totalnumberoffiles)
            {
                lblMessage.Text += "Please select only " + totalnumberoffiles + " files.";
                lblMessage.Visible = true;
            }
            else
            {
                double fileProgressPercentagePortion = 100 / attachments.Count;
                double fileProgressPercentage = 0;
                double fileProgressPercentageSegment = fileProgressPercentagePortion/6;
                for (int i = 0; i < attachments.Count; i++)
                {
                    HttpPostedFile attachment = attachments[i];

                    if (attachment.FileName == string.Empty)
                    {
                        continue;
                    }

                    hubContext.Clients.All.AddProgress("Currently processing: ", new System.IO.FileInfo(attachment.FileName).Name, "0", 
                        Context.User.Identity.Name, pageName);
                    if (attachment.ContentLength > 0 && !String.IsNullOrEmpty(attachment.FileName))
                    {
                        hubContext.Clients.Client(hubContext.co).AddProgress("Currently processing: ", new System.IO.FileInfo(attachment.FileName).Name, 
                            fileProgressPercentageSegment, Context.User.Identity.Name, pageName);

                        ProcessFile(attachment, hubContext, fileProgressPercentageSegment, 
                                fileProgressPercentage);
                        fileProgressPercentage += fileProgressPercentagePortion;
                    }
                }
            }
        }
    }
    catch (Exception e3)
    {

    }
    finally
    {

    }
}

这是我的 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);
    });

});

这里是我的中心

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()
        {

        }
    }
}

【问题讨论】:

  • 您可以只使用Clients.Caller 只响应调用您方法的人
  • 谢谢@MindSwipe,但是,由于某种原因,我在 asp.net SignalR 中无法使用“Caller”属性。我应该使用其他属性吗?感谢您的反馈
  • 不清楚您在何时何地为您的客户调用 AddProgress 事件。你能发送“hubContext.Clients.All.AddProgress(..)”调用所在的代码块吗?
  • @NthDeveloper 刚刚发了一个完整的事件方法,谢谢

标签: c# asp.net webforms signalr


【解决方案1】:

如果您只想响应调用服务器端方法的人,可以像这样使用Clients.Caller 属性:

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

【讨论】:

  • 非常感谢您的建议!看起来确实很有帮助;但是,不幸的是,Caller 属性不可用。那是因为我使用的是 WenForms,而不是 MVC?我应该使用可用的 AllExcept、Users 或 Client 方法吗?再次感谢您的帮助
  • 你能把你的代码贴在hubContext被声明和分配的地方吗?
  • 不,你没有。您添加了 btnSubmit_Click 方法,而不是您声明 hubContext 的位置,也不是您为 hubContext 分配值的位置
  • 其实我做到了。它在我发布的代码中。以防万一我只是阻止引用,所以它会脱颖而出。如果您需要更多信息,请告诉我
  • 所以,为了检查我是否正确,您有一个托管 SignalR 集线器的 ASP.NET 应用程序,然后您有一个调用它的 WinForms 应用程序,以及您有JavaScript 也调用它?
【解决方案2】:

在我的aspx中找到了解决方案

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

我将连接 ID 设置为隐藏字段

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

在代码隐藏中我现在有了

hubContext.Clients.Client(hfConnectionId.Value).AddProgress("Currently processing: ", fn4, currentProgress, Context.User.Identity.Name, pageName);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-29
    • 2016-08-19
    • 2017-05-09
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多