我正在使用带有PostgreSQL数据库(带有Npgsql(的.NET Core应用程序与SignalR相结合来接收实时数据和最新数据条目。但是,我没有收到最新的条目,有时Clients.All.SendAsync
方法会向客户端发送多个条目。这是我的代码:
将新数据发送到客户端的中心方法:
public async Task SendForexAsync(string name)
{
var product = GetForex(name);
await Clients.All.SendAsync("CurrentData", product);
using (var conn = new NpgsqlConnection(ApplicationDbContext.GetConnectionString()))
{
conn.Open();
var cmd = new NpgsqlCommand("LISTEN new_forex", conn).ExecuteNonQuery();
conn.Notification += async (o, e) =>
{
var newProduct = GetForex(name);
await Clients.All.SendAsync("NewData", newProduct);
};
while (true)
{
await conn.WaitAsync();
}
}
}
定期从 API 轮询新数据的控制台应用:
var addedStocksDJI = FetchNewStocks("DJI");
if (addedStocksAAPL > 0 || addedStocksDJI > 0)
{
using (var conn = new NpgsqlConnection(ApplicationDbContext.GetConnectionString()))
{
conn.Open();
var cmd = new NpgsqlCommand("NOTIFY new_stocks", conn).ExecuteNonQuery();
}
}
该应用程序的其他代码绝对是正确的,因为在尝试实现 LISTEN/NOTIFY 功能之前,我收到了新的和正确的数据。但是现在,我在客户端上获得了一个(或多个(newProduct
条目,但它是"旧"产品,即数据库不查询和发送最新条目,而仅通过 SignalR 发送旧条目。但是,当我手动刷新页面时,新数据会正确显示。
我相信这与打开的单个连接有关,所以我经常只接收"旧"数据集,但即使是这种情况,我也无法弄清楚为什么我有时会收到多个数据包,即使我只是尝试发送一个,而且我只调用NOTIFY
一次。
我想通了。希望这将帮助将来遇到这种情况的其他人!
问题是我通过Hub
类中的 .NET Core 依赖注入声明我的dbContext
,该类每个类只创建一次上下文,也因为每个页面或 WebSocket 事务。这就是为什么我无法获得最新数据的原因,我认为,因为dbContext
是"旧的"并且不知道变化。
我通过在方法内部通过using
方案使用dbContext
解决了这个问题,在我的SendForexAsync
方法中使用了两次(每次调用GetForex
函数一次(,以及在GetForex
函数本身中。这样,将立即创建并释放dbContext
,因此下次我通过GetForex
函数轮询数据库以获取新数据时(当我由于控制台应用程序的NOTIFY
而收到来自数据库的通知时(,将创建一个可以包含该新数据的新dbContext
实例。