使用带有SignalR的SqlDepedency OnChange事件会在每次刷新时添加新的全局事件,并且每次新客户端都连接

时间:2015-07-20 00:57:23

标签: c# signalr onchange signalr-hub sqldependency

通常我会通过在这里阅读帖子来解决问题,但这次我似乎无法找到问题的具体答案。

我一直在尝试使用SignalR将数据库更改推送到使用SqlDependency连接的每个客户端 - 这并没有花费我很长时间才能完成。问题是,每个教程都提供了关于如何向用户/客户端推送通知的完全相同的示例,但我似乎无法使其工作。

我的代码如下所示:

启动

我的应用开始时初始化以下行:

SqlDependency.Start(DbProvider.MyApp.ConnectionString);

然后我创建了我的启动类:

[assembly: OwinStartup(typeof(Startup))]
namespace MyApp.Web.SignalR
{
  public class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      app.MapSignalR();
    }
  }
}

NotificationHub:Hub

我根据ASP.NET网站和其他博客的指南设置了我的中心:

namespace MyApp.Web.SignalR
{
  public class NotificationHub : Hub
  {
    public void SendNotifications()
    {
      string message = string.Empty;
      using (var connection = new SqlConnection(DbProvider.MyApp.ConnectionString))
      {
        using (var command = new SqlCommand("SELECT [Test] FROM [dbo].[Test]", connection))
        {
          try
          {
            command.Notification = null;

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

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

            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
              reader.Read();
              message = reader[0].ToString();
            }
          }
          catch (Exception ex)
          {
            throw;
          }
        }
      }
      IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();
      context.Clients.All.addNewMessageToPage("db", message);
    }

    private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
    {
      var dependency = (SqlDependency) sender;
      dependency.OnChange -= dependency_OnChange;
      if (e.Type == SqlNotificationType.Change)
      {
        SendNotifications();
      }
    }
  }
}

的Javascript

最后,我使用这段代码来调用方法并从服务器接收通知:

<script type="text/javascript">
  $(function () {
    var notifications = $.connection.notificationHub;

    notifications.client.addNewMessageToPage = function (name, message) {
      console.log(name, message);
    };

    $.connection.hub.start().done(function () {
      notifications.server.sendNotifications();
    }).fail(function (e) {
      alert(e);
    });
  });
</script>

根据我所遇到的所有教程,这应该可以解决问题 - 而且确实如此......

每当我更改查询中指定的表时,我都会收到通知, 实际上被推送到客户端但是当我刷新或访问我的localhost时出现问题来自另一个客户 - 事件似乎堆积如山,我无法在任何地方捕获和取消订阅。

示例

我打开我的网页并更新我的数据库 - 一个通知发送给客户端,并且它应该始终如何。如果我刷新浏览器,则在进行数据库更新时会发送两个通知。而且,如果我从另一个客户端访问我的本地主机 - 让我们说智能手机 - 每次数据库更新都会发送三个通知。这基本上意味着在每个请求上订阅一个新事件并且#34;旧事件&#34;仍然存在(他们不应该)。

由于我在C#中处理线程和处理事件仍然很陌生,也许还有一些我根本看不到的东西 - 我希望你们中的一些人可以帮助我解决这个问题出来了!而且我甚至都不会告诉我花了多少时间在这件事上 - 这太尴尬了。)

如果您有任何疑问或者我遗漏了一些可能有用的信息,请回复!

/安德斯

0 个答案:

没有答案