Using SqlDepedency OnChange event with SignalR adds new global event on each refresh and each time new client connects

大兔子大兔子 提交于 2019-12-25 16:38:31

问题


Usually I manage to solve a problem by reading posts here, but this time I can't seem to find the specific answer to my problem.

I've been trying SignalR for pushing database changes to each client connected using SqlDependency - this didn't take me long to accomplish. The problem is that each tutorial is giving the exact same examples on how to push notifications to the users/clients, but I can't seem to get it to work.

My code looks like this:

Startup

I initialize the following line when my app starts:

SqlDependency.Start(DbProvider.MyApp.ConnectionString);

And then I create my startup-class:

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

NotificationHub : Hub

I set up my Hub according to the guidelines from the ASP.NET-website and other blogs:

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

And finally I use this little piece of code to invoke methods and recieve notifications from the server:

<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>

According to all tutorials I've come across, this should do the trick - and it does - sort of..

I do get notified whenever I change the table specified in my query, it does actually get pushed to the client but the problem occurs when I refresh or access my localhost from another client - the events just seem to pile up and I can't catch and unsubscribe them anywhere.


Example

I open my webpage and update my database - one notification is sent to the client and that's how it should always be. If I refresh my browser there are two notifications being sent on when I do a database update. And again, if I access my localhost from another client - let's say a smartphone - three notifications are sent on each database update. This basically means that on each request a new event is subscribed and "the old ones" still exist (which they shouldn't).


As I'm still quite new to threading and working with events in C#, maybe there's something that I'm simply not seeing - I hope some of you guys can help me figure this thing out! And I'm not even going to tell how much time I've spent on this thing - that would be too embarrasing :)

Please reply if you have any questions or if I've left out some potentially useable information!

/Anders

来源:https://stackoverflow.com/questions/31507543/using-sqldepedency-onchange-event-with-signalr-adds-new-global-event-on-each-ref

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!