上下文是 SQL Server 表依赖项不起作用,但我的 SignalR 工作正常。没有错误表明它只是当我通过 SSMS 更改一些数据时,下面的代码被触发。
private void TableDependency_OnChanged(object sender, TableDependency.SqlClient.Base.EventArgs.RecordChangedEventArgs<Announcement> e)
{
if (e.ChangeType != TableDependency.SqlClient.Base.Enums.ChangeType.None)
{
announcementHub.NotifyAnnouncement();
}
}
这是我在数据库有更新时处理的代码:
public async Task NotifyAnnouncement()
{
await Clients.All.SendAsync("ShowAnnouncement");
}
这是我中心的代码:
const connection = new signalR.HubConnectionBuilder()
.withUrl("/resident/home")
.build();
connection.start().then(function () {
alert('Connected to home');
}).catch(function (err) {
return console.error(err.toString());
});
connection.on("ShowAnnouncement", function () {
toastr.info("something new");
updateAnnouncement();
});
这是我在客户端的脚本 - 当我通过系统插入新数据时,此代码工作正常,因为插入数据后我放置了此代码
await _hubContext.Clients.All.SendAsync("ShowAnnouncement");
控制器内部。然后它反映到我的客户端。
我不知道是否应该在
SqlTableDependency
代码中调用控制器,或者是否可以这样做,以便它反映到客户端?
我刚开始使用 SignalR 和
SqlTableDependency
。希望您能理解,谢谢。
我已经在 ssms 中启用了 is_broker。
我建议你可以按照下面的步骤和代码来检查为什么你的sql依赖不起作用。
1.确保您已启用sql
ALTER DATABASE YourDatabaseName SET ENABLE_BROKER;
2.确保您已设置好SqlDependency。使用正确的 sql 查询传递
SqlCommand
。
IEmployeeRepository:
public interface IEmployeeRepository
{
List<Employee> GetAllEmployees();
}
public class EmployeeRepository : IEmployeeRepository
{
private readonly IHubContext<SignalServer> _context;
string connectionString = "";
public EmployeeRepository(IConfiguration configuration, IHubContext<SignalServer> context)
{
connectionString = configuration.GetConnectionString("DefaultConnection");
_context = context;
}
public List<Employee> GetAllEmployees()
{
var employees = new List<Employee>();
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlDependency.Start(connectionString);
string commandText = "select Id, Name, Age from dbo.Employees";
SqlCommand cmd = new SqlCommand(commandText, conn);
SqlDependency dependency = new SqlDependency(cmd);
dependency.OnChange += new OnChangeEventHandler(dbChangeNotification);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
var employee = new Employee
{
Id = Convert.ToInt32(reader["Id"]),
Name = reader["Name"].ToString(),
Age = Convert.ToInt32(reader["Age"])
};
employees.Add(employee);
}
}
return employees;
}
private void dbChangeNotification(object sender, SqlNotificationEventArgs e)
{
_context.Clients.All.SendAsync("refreshEmployees");
}
}
集线器方式:
public class SignalServer : Hub
{
}
控制器:
public class EmployeeController : Controller
{
private readonly IEmployeeRepository _repository;
public EmployeeController(IEmployeeRepository repository)
{
_repository = repository;
}
public IActionResult Index()
{
return View();
}
[HttpGet]
public IActionResult GetEmployees()
{
return Ok(_repository.GetAllEmployees());
}
}
查看:
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
</table>
@section Scripts{
<script src="~/microsoft/signalr/dist/browser/signalr.js"></script>
<script>
$(() => {
//build the hub connection
let connection = new signalR.HubConnectionBuilder().withUrl("/signalServer").build()
connection.start()
connection.on("refreshEmployees", function () {
loadData() //after database change, it will call this function to refresh the data.
})
loadData(); //when page load call the loadData method to display the data.
function loadData() {
var tr = ''
$.ajax({
url: '/Employee/GetEmployees',
method: 'GET',
success: (result) => {
$.each(result, (k, v) => {
tr = tr + `<tr>
<td>${v.id}</td>
<td>${v.name}</td>
<td>${v.age}</td>
</tr>`
})
$("#tableBody").html(tr)
},
error: (error) => {
console.log(error)
}
})
}
})
</script>
}
未修改:
将Jason名称修改为Jasontest