微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SignalR 向同一用户发送重复消息 n 次 n 是连接的用户数 .NetCore

如何解决SignalR 向同一用户发送重复消息 n 次 n 是连接的用户数 .NetCore

我有 SignalR ASP.NET Core 项目,并尝试向特定用户发送消息,我设法这样做了。问题是相同的消息发送 n 时间 n=number 的选项卡或连接,当数据库发生更改时,它会向该特定用户发送通知,但会重复该消息。

public class MessageHub: Hub
{       
    public MessageHub(IConfiguration cc,IHubContext<MessageHub> _mess,UserManager<ApplicationUser> rep)
    {
        mess = _mess;
        _conf = cc;
        _usermanager = rep;
        RegisterNotification();
    }

    public void RegisterNotification()
    {        
        using (sqlConnection con = new sqlConnection(conStr))
        {
            sqlCommand cmd = new sqlCommand(sqlCommand,con);

            if (con.State != System.Data.ConnectionState.Open)
            {
                con.open();
            }

            cmd.Notification = null;
        
            sqlDependency sqlDep = new sqlDependency(cmd);
          
            sqlDep.OnChange += sqlDep_OnChange;
          
            using (sqlDataReader reader = cmd.ExecuteReader())
            {
                // nothing need to add here Now
            }
        }
    }

    static int count = 1;
    private  void sqlDep_OnChange(object sender,sqlNotificationEventArgs e)
    {
        if (e.Type == sqlNotificationType.Change )
        {
            sqlDependency sqlDep = sender as sqlDependency;
            sqlDep.OnChange -= sqlDep_OnChange;
                      
            mess.Clients.User("64ed09d7-255f-4aae-a25f-7a50e59943b4").SendAsync("abc","hello"+count);
            count += 1;

           RegisterNotification();
        }
    }
}

enter image description here

解决方法

正如您所提到的,问题是每次创建 RegisterNotification 实例时都会调用 MessageHub。取而代之的是,您可以创建后台服务并在那里注册到 SqlDependency 并使用 IHubContext 发送事件。每次通知后,您再次调用 RegisterNotification,这也可能导致重复。

我还没有测试过这段代码,但这里有一个例子:

public class EventBroadcaster : IHostedService
{
    private readonly IHubContext<MessageHub> _hubContext;
    private readonly string _connectionString;

    public EventBroadcaster(
           IConfiguration configuration,IHubContext<MessageHub> hubContext)
    {
         _hubContext = hubContext;
         _connectionString = // Get Connection String from configuration
    }

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Started event broadcasting service");

        RegisterNotification();
        return Task.CompletedTask;
    }


    public void RegisterNotification()
    {        
        using (SqlConnection con = new SqlConnection(_connectionString))
        {
            SqlCommand cmd = new SqlCommand(sqlCommand,con);

            if (con.State != System.Data.ConnectionState.Open)
            {
                con.Open();
            }

            cmd.Notification = null;
        
            SqlDependency sqlDep = new SqlDependency(cmd);
          
            sqlDep.OnChange += sqlDep_OnChange;
          
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                // nothing need to add here now
            }
        }
    }

    static int count = 1;
    private async void sqlDep_OnChange(object sender,SqlNotificationEventArgs e)
    {
        if (e.Type == SqlNotificationType.Change )
        {
            SqlDependency sqlDep = sender as SqlDependency;
            sqlDep.OnChange -= sqlDep_OnChange;
                      
            await _hubContext.Clients.User("64ed09d7-255f-4aae-a25f-7a50e59943b4").SendAsync("abc","hello"+count);

            count += 1;
        }
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Event Broadcasting Service is stopping.");

        // TODO: Stop listening to SqlDependency notifications

        return Task.CompletedTask;
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。