如何在SignalR中向中心传递参数?

6

我的SignalR hub中的代码:

public class AlertHub : Hub
{
    public static readonly System.Timers.Timer _Timer = new System.Timers.Timer();

    static AlertHub()
    {
        _Timer.Interval = 60000;
        _Timer.Elapsed += TimerElapsed;
        _Timer.Start();
    }

    static void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        //Random rnd = new Random();
        //int i = rnd.Next(0,2);
        Alert alert = new Alert();
        i = alert.CheckForNewAlerts(EmpId);

        var hub = GlobalHost.ConnectionManager.GetHubContext("AlertHub");

        hub.Clients.All.Alert(i);
    }
}

我需要传递EmpId参数,该如何实现?

更多客户端细节:在我的aspx页面上,我有以下代码:

<script type="text/javascript">

    $(function () {
        var alert = $.connection.alertHub;
        alert.client.Alert = function (msg) {
            if (msg == 1) {
                $("#HyperLink1").show();
                $("#HyperLink2").hide();

            }
            else {
                $("#HyperLink1").hide();
                $("#HyperLink2").show();
            }
            //$("#logUl").append("<li>" + msg + "</li>");
        };
        $.connection.hub.start();
    });

</script>

在ASPX页面中,我的EmpID存储在会话对象中,我需要以某种方式在SignalR Hub中使用它。

EmpId 是从哪里来的? - devshorts
那就是我需要传递的,但我不知道在哪里以及如何实现。 - WinFXGuy
我不确定我理解了。那个属性是什么意思,如果你知道如何传递它,你会在哪里访问它?它可以从其他地方公开吗?你将无法在构造函数中传递任何内容,因为你不负责创建 Hub。你希望 Hub 拥有的任何内容都需要它已经知道或从其他地方获取。 - devshorts
我为你更新了我的答案。 - devshorts
3个回答

7
除了接受的答案,我还使用了以下方法将多个查询字符串从客户端传递到中心: 在客户端:
Dictionary<string, string> queryString = new Dictionary<string, string>();
        queryString.Add("key1", "value1");
        queryString.Add("key2", "value2");
        hubConnection = new HubConnection("http://localhost:49493/signalr/hubs", queryString);

---代码的其余部分--------

在Hub类中:

public override Task OnConnected()
{
 var value1 = Convert.ToString(Context.QueryString["key1"]);
 var value2 = Convert.ToString(Context.QueryString["key2"]);
 return base.OnConnected();
}

我正在使用版本为“2.3.0.0”的“Microsoft.AspNet.SignalR.Client”库,用于使用C#编写的Windows表单应用程序。


4

您可以通过连接(查看此处此处示例)跟踪已连接的用户(以及任何相关元数据),在定时器记号上检查您存储的本地数据以获取所需内容。

独立使用signalR无法传递任何信息。 客户端必须传递信息。

如果客户端有员工ID,请在连接时将其发送到signalr中心。 您可以在aspx页面JavaScript中添加处理程序,以便知道客户端连接情况,然后将其发送到中心。 中心可以在字典中跟踪ConnectionId,EmployeeID,您可以使用它来访问特定的客户端或执行其他操作。

请查看我发布的链接,它们展示了如何执行此操作。


1
如何在客户端连接时发送EmpId? 这是我在客户端连接到中心的方法。var alert = $.connection.alertHub; 请告诉我如何添加一个处理程序来处理客户端连接。 - WinFXGuy
1
http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client#querystring - halter73
1
@WinFXGuy,@halter73的链接展示了如何在start()方法上注册一个函数来调用回调。此时,只需将您想要发送的任何内容发送到中心即可。 - devshorts
1
谢谢大家。我的其他SO问题解决了这个问题。https://dev59.com/on3aa4cB1Zd3GeqPakKi - WinFXGuy
@devshorts 如果我像你建议的那样在字典中保存与我的用户关联的连接ID,那么如果用户刷新页面,我该如何重新打开该连接。是否有一种方法可以在特定的连接ID上调用 $.connection.hub.start() - user95227

2
在ASP.NET Core 6中(不确定早期版本),您可以在hub路径中包含参数。
在Program.cs文件中:
app.MapHub<AlertHub>("/myhub/{EmpId}");

在AlertHub类中,可以使用Context.GetHttpContext().GetRouteValue("EmpId")引用EmpId参数,例如将连接添加到群组:

public override async Task OnConnectedAsync()
{
    var id = Context?.GetHttpContext()?.GetRouteValue("EmpId") as string;
    await Groups.AddToGroupAsync(Context?.ConnectionId, id);
    await base.OnConnectedAsync();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接