如何使用 signalR 通知数据库更改
How to notify database changes with signalR
我刚开始使用 SignalR,想尝试实时通知。 objective 是在网页上持续显示更新的消息。
有一个数据库 table - DummyData
,其中有一列 Message
。此 table 只有一条记录 - Hello
页面加载时,显示 "Hello"。
然后我手动 运行 sql 服务器 2012 中的命令
update DummyData set Message='hello world'
,但该消息未在网页中更新。
aspx:
<script>
$(function () {
var notify = $.connection.notificationsHub;
$.connection.hub.start().done(function () {
notify.server.notifyAllClients();
});
notify.client.displayNotification = function (msg) {
$("#newData").html(msg);
};
notify.client.stopClient = function () {
$.connection.hub.stop();
};
});
</script>
<span id="newData"></span>
aspx.cs:
public string SendNotifications()
{
string message = string.Empty;
using (SqlConnection connection = new SqlConnection(conStr))
{
string query = "SELECT [Message] FROM [dbo].[DummyData]";
SqlCommand command = new SqlCommand(query, connection)
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
message = reader[0].ToString();
}
}
return message;
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
SendNotifications();
}
}
NotificationsHub.cs
public class NotificationsHub : Hub
{
Messages obj = new Messages();
public void NotifyAllClients(string msg)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>();
context.Clients.All.displayNotification(msg);
}
public override System.Threading.Tasks.Task OnConnected()
{
NotifyAllClients();
return base.OnConnected();
}
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
NotifyAllClients();
return base.OnDisconnected(stopCalled);
}
}
global.asax:
protected void Application_Start(object sender, EventArgs e)
{
SqlDependency.Start(Constr);
}
当我 运行 tsql 更新命令时,断点首先在 dependency_OnChange
命中,我可以看到从 SendNotification
返回的新更新文本.但它没有反映在页面上。感觉我快到了,但缺少一些东西。
Signalr 没有监视您的数据库的变化。因此,当您只是将用户在数据库中设置为非活动状态时,它对 Signalr 没有任何意义。您的 3 个客户端仍处于连接状态。
要获得所需的结果,请将类似的内容添加到您的 Hub
public override OnConnected()
{
// Increase the active user count in the db
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ServerHub>();
Clients.All.broadcastCount(DB.GetCount());
return base.OnConnected();
}
public override OnDisconnected()
{
//Decrease the connected user count in the db
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ServerHub>();
Clients.All.broadcastCount(DB.GetCount());
return base.OnDisconnected();
}
然后当您连接和断开客户端时,集线器将通知连接的客户端。
您将需要以 SignalR 将捕获的方式断开连接,因此您不能只更改数据库中的标志。尝试从您的客户端调用 $.connection.hub.stop();
。
This link 详细介绍。
如果你说 dependency_OnChange
事件在你更新数据库后被触发,那么不是调用 SendNotifications();
,而是调用一个集线器方法,具体来说 NotifyAllClients(...)
我刚开始使用 SignalR,想尝试实时通知。 objective 是在网页上持续显示更新的消息。
有一个数据库 table - DummyData
,其中有一列 Message
。此 table 只有一条记录 - Hello
页面加载时,显示 "Hello"。
然后我手动 运行 sql 服务器 2012 中的命令
update DummyData set Message='hello world'
,但该消息未在网页中更新。
aspx:
<script>
$(function () {
var notify = $.connection.notificationsHub;
$.connection.hub.start().done(function () {
notify.server.notifyAllClients();
});
notify.client.displayNotification = function (msg) {
$("#newData").html(msg);
};
notify.client.stopClient = function () {
$.connection.hub.stop();
};
});
</script>
<span id="newData"></span>
aspx.cs:
public string SendNotifications()
{
string message = string.Empty;
using (SqlConnection connection = new SqlConnection(conStr))
{
string query = "SELECT [Message] FROM [dbo].[DummyData]";
SqlCommand command = new SqlCommand(query, connection)
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
message = reader[0].ToString();
}
}
return message;
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
SendNotifications();
}
}
NotificationsHub.cs
public class NotificationsHub : Hub
{
Messages obj = new Messages();
public void NotifyAllClients(string msg)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<NotificationsHub>();
context.Clients.All.displayNotification(msg);
}
public override System.Threading.Tasks.Task OnConnected()
{
NotifyAllClients();
return base.OnConnected();
}
public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled)
{
NotifyAllClients();
return base.OnDisconnected(stopCalled);
}
}
global.asax:
protected void Application_Start(object sender, EventArgs e)
{
SqlDependency.Start(Constr);
}
当我 运行 tsql 更新命令时,断点首先在 dependency_OnChange
命中,我可以看到从 SendNotification
返回的新更新文本.但它没有反映在页面上。感觉我快到了,但缺少一些东西。
Signalr 没有监视您的数据库的变化。因此,当您只是将用户在数据库中设置为非活动状态时,它对 Signalr 没有任何意义。您的 3 个客户端仍处于连接状态。
要获得所需的结果,请将类似的内容添加到您的 Hub
public override OnConnected()
{
// Increase the active user count in the db
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ServerHub>();
Clients.All.broadcastCount(DB.GetCount());
return base.OnConnected();
}
public override OnDisconnected()
{
//Decrease the connected user count in the db
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ServerHub>();
Clients.All.broadcastCount(DB.GetCount());
return base.OnDisconnected();
}
然后当您连接和断开客户端时,集线器将通知连接的客户端。
您将需要以 SignalR 将捕获的方式断开连接,因此您不能只更改数据库中的标志。尝试从您的客户端调用 $.connection.hub.stop();
。
This link 详细介绍。
如果你说 dependency_OnChange
事件在你更新数据库后被触发,那么不是调用 SendNotifications();
,而是调用一个集线器方法,具体来说 NotifyAllClients(...)