SignalR客户端方法触发多次
本文关键字:客户端 方法 SignalR | 更新日期: 2023-09-27 18:06:27
我正在玩SignalR,试图在谷歌地图上创建一个热图覆盖。然而,我的方法是触发多次,我不知道为什么。
从SQL返回的数据被格式化为JSON,所以我可以使用这个插件- http://www.patrick-wied.at/static/heatmapjs/
将其绘制到覆盖上我一直在跟随在http://techbrij.com/database-change-notifications-asp-net-signalr-sqldependency上找到的web api演示,但没有运气。我的代码如下:
视图(剪辑以显示相关代码)
<script type="text/javascript">
var map;
var heatmap;
var testData;
$(function () {
// Proxy created on the fly
var sales = $.connection.productSalesHub;
// Declare a function on the product sales hub so the server can invoke it
sales.client.displaySales = function () {
getSalesData();
};
// Start the connection
$.connection.hub.start();
getSalesData();
});
function getSalesData() {
$.ajax({
url: '../api/values',
type: 'GET',
datatype: 'json'
})
.done(function (res) {
if (res.length > 0) {
var myLatlng = new google.maps.LatLng(48.3333, 16.35);
// sorry - this demo is a beta
// there is lots of work todo
// but I don't have enough time for eg redrawing on dragrelease right now
var myOptions = {
zoom: 2,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.SATELLITE,
disableDefaultUI: false,
scrollwheel: true,
draggable: true,
navigationControl: true,
mapTypeControl: false,
scaleControl: true,
disableDoubleClickZoom: false
};
testData = res;
map = new google.maps.Map(document.getElementById("heatmapArea"), myOptions);
heatmap = new HeatmapOverlay(map, {
"radius": 15,
"visible": true,
"opacity": 60,
legend: {
position: 'br',
title: 'Amount of items sold'
}
});
google.maps.event.addListenerOnce(map, "idle", function() {
heatmap.setDataSet(testData);
});
}
})
.fail(function () {
alert("error");
})
.always(function() {
alert("complete");
});
}
</script>
值控制器:
public class ValuesController : ApiController
{
ProductSalesRepository repo = new ProductSalesRepository();
// GET api/values
public JObject Get()
{
var data = repo.GetProductSalesData();
return repo.BuildJson(data);
}
}
ProductSalesHub.cs
public class ProductSalesHub : Hub
{
public static void Show()
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<ProductSalesHub>();
context.Clients.All.displaySales();
}
}
最后,我的repo
public class ProductSalesRepository
{
public IEnumerable<ProductSalesInfo> GetProductSalesData()
{
using (
var connection =
new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand(@"SELECT top 10 [lat],[lng],[count]
FROM [dbo].[ProductSales]", connection))
{
// Make sure the command object does not already have
// a notification object associated with it.
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
if (connection.State == ConnectionState.Closed)
connection.Open();
using (var reader = command.ExecuteReader())
return reader.Cast<IDataRecord>()
.Select(x => new ProductSalesInfo()
{
Lat = x.GetString(0),
Long = x.GetString(1),
Count = x.GetInt32(2)
}).ToList();
}
}
}
public JObject BuildJson(IEnumerable<ProductSalesInfo> data )
{
IEnumerable<ProductSalesInfo> productSalesInfos = data as List<ProductSalesInfo> ?? data.ToList();
int max = (from d in productSalesInfos.ToList() select d.Count).Max();
JObject o = new JObject(
new JProperty("max", max),
new JProperty("data",
new JArray(from d in productSalesInfos
select new JObject(
new JProperty("lat", d.Lat),
new JProperty("lng", d.Long),
new JProperty("count", d.Count)))));
return o;
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
ProductSalesHub.Show();
}
}
我已经盯着这个几个小时了,没有弄清楚为什么ajax调用被触发多次。
任何想法?
我也遇到过同样的问题。我正在注入我的存储库类,并且有它的多个实例。这里每次调用GetProductSalesData()方法时都添加事件。我会在构造函数中添加一次事件,并使用单例模式来确保它只被调用一次。
因为每个打开页面的客户端都通过signalR和signalR响应向所有客户端请求服务器,这就是为什么你会看到多个响应和请求。使用
this.Clients.Client(this.Context.ConnectionId).displaySales();
不是 context.Clients.All.displaySales();
欢呼。