SignalR 向同一用户发送重复消息 n 次 n 是连接的用户数.NetCore
SignalR send duplicate message to same user n times n is number of users connected .NetCore
我有 SignalR ASP.NET 核心项目并尝试向我设法发送消息的特定用户发送消息。问题是相同的消息发送 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();
}
}
}
正如您所提到的,问题是每次创建 MessageHub
的实例时都会调用 RegisterNotification
。取而代之的是,您可以创建后台服务并在那里注册 SqlDependency
,然后使用 IHubContext
发送事件。在每次通知后,您再次调用 RegisterNotification
,这也可能导致重复。
- https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
- https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext
我还没有测试过这段代码,但这里有一个例子:
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;
}
我有 SignalR ASP.NET 核心项目并尝试向我设法发送消息的特定用户发送消息。问题是相同的消息发送 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();
}
}
}
正如您所提到的,问题是每次创建 MessageHub
的实例时都会调用 RegisterNotification
。取而代之的是,您可以创建后台服务并在那里注册 SqlDependency
,然后使用 IHubContext
发送事件。在每次通知后,您再次调用 RegisterNotification
,这也可能导致重复。
- https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
- https://docs.microsoft.com/en-us/aspnet/core/signalr/hubcontext
我还没有测试过这段代码,但这里有一个例子:
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;
}