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