简体   繁体   English

SignalR向特定客户端发送消息

[英]SignalR send message to specific client

I have a hub with a static method which broadcasts notifications to all users currently. 我有一个带静态方法的集线器,它向当前所有用户广播通知。

public class NotificationHub : Hub
{
    private static string connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString();

    [HubMethodName("sendNotifications")]
    public static void SendNotifications()
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
        context.Clients.All.updateNotifications();
    }
}

I need to take some text box input from the front end javascript eg 10038 which is the userID and send this to a server class eg 我需要从前端javascript中输入一些文本框输入,例如10038,这是userID并将其发送到服务器类,例如

public class NotificationRepository
{
    private readonly string _connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

    public IEnumerable<Notifications> GetNotifications(int userID)
    {
        var notifications = new List<Notifications>();

        using (var connection = new SqlConnection(_connString))
        {
            connection.Open();
            using (var command = new SqlCommand(String.Format(@"SELECT [ID], [UserID], [Message] FROM [dbo].[Notification] WHERE [UserID] = {0}", userID), connection))
            {
                command.Notification = null;

                var dependency = new SqlDependency(command);
                dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);

                if (connection.State == ConnectionState.Closed)
                {
                    connection.Open();
                }

                var reader = command.ExecuteReader();

                while (reader.Read())
                {
                    notifications.Add(item: new Notifications { ID = (int)reader["ID"], UserID = (int)reader["UserID"], Message = (string)reader["Message"] });
                }
            }
        }
        return notifications;
    }

    private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
        if (e.Type == SqlNotificationType.Change)
        {
            NotificationHub.SendNotifications();
        }
    }
}

I return a set of notifications for the specific user as defined by the User ID but I can't seem to figure out how I map the response so that I only return notifications to that specific client in signalR. 我为用户ID定义的特定用户返回一组通知,但我似乎无法弄清楚如何映射响应,以便我只向signalR中的特定客户端返回通知。

How do I go about mapping the connection IDs of the clients to the userID that was entered? 如何将客户端的连接ID映射到输入的用户ID?

I have read the signalR documentation but it's very vague and other solutions online don't seem to address this specific issue. 我已阅读signalR文档,但它非常模糊,其他在线解决方案似乎无法解决此特定问题。

Any help would be much appreciated. 任何帮助将非常感激。

EDIT 编辑

So far I have tried using IUserIdProvider and this is what I have so far but this does not seem to work. 到目前为止,我已经尝试使用IUserIdProvider,这是我到目前为止所做的,但这似乎不起作用。

On the front end I have set my queryString as follows 在前端我设置了queryString如下

$.connection.hub.qs = "userId=" + $('#userText').val();

This is my custom IUserIdProvider 这是我的自定义IUserIdProvider

public class CustomUserIdProvider : IUserIdProvider
{
    public string GetUserId(IRequest request)
    {
         return request.QueryString["userId"];
     }
 }

This is what my NotificationRepository looks like 这就是我的NotificationRepository的样子

public class NotificationRepository
{
    private readonly string _connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

    public IEnumerable<Notifications> GetUserNotifications(string userID)
    {
        var notifications = new List<Notifications>();

        using (var connection = new SqlConnection(_connString))
        {
            connection.Open();
            using (var command = new SqlCommand(String.Format(@"SELECT [ID], [UserID], [Message] FROM [dbo].[Notification] WHERE [UserID] = {0}", userID), connection))
            {
                command.Notification = null;

                var dependency = new SqlDependency(command);
                dependency.OnChange += new OnChangeEventHandler((sender, e) => dependency_OnChange(sender, e, userID));

                if (connection.State == ConnectionState.Closed)
                {
                    connection.Open();
                }

                var reader = command.ExecuteReader();

                while (reader.Read())
                {
                    notifications.Add(item: new Notifications { ID = (int)reader["ID"], UserID = (int)reader["UserID"], Message = (string)reader["Message"] });
                }
            }
        }
        return notifications;
    }


    private void dependency_OnChange(object sender, SqlNotificationEventArgs e, string userID)
    {
        if (e.Type == SqlNotificationType.Change)
        {
            NotificationHub.SendNotifications(userID);
        }
    }
}

And this is my hub 这是我的中心

public class NotificationHub : Hub
{
    private static string connString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString();

    [HubMethodName("sendNotifications")]
    public static void SendNotifications(string userId)
    {
        IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
        context.Clients.Client(userId).updateNotifications();
    }
}

So I've figured out what the issue is in this scenario. 所以我已经弄清楚了这个场景中的问题。 When initialising the queryString 初始化queryString时

 $.connection.hub.qs = "userId=" + $('#userText').val(); 

You must do this before you start the connection to the hub. 在开始与集线器的连接之前,必须执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM