如何使用 SignalR 显示来自 REST API 的实时数据?
How to display live data from REST API with SignalR?
我有 REST API,每隔几分钟就会 return 新数据。如何在不让用户每次都刷新浏览器的情况下显示新数据?
这是我目前所拥有的。
AppController.cs
public IActionResult Index()
{
string[] day = {"Mon", "Tue", "Wed", "Thu", "Fri"};
List<API> results = new List<API>();
for (var i = 0; i < day.Length; i++)
{
var client = new RestClient("https://api.example.com/values/d=" + day[i]);
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("accept", "application/json; charset=utf-8");
IRestResponse response = client.Execute(request);
var responseContent = response.Content;
results.Add(new JavaScriptSerializer().Deserialize<API>(responseContent));
}
return View(results);
}
APIHub.cs
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace SignalRAPI.Hubs
{
public class APIHub : Hub
{
public async Task SendData( )
{
await Clients.All.SendAsync( );
}
}
}
index.cshtml
@model Site.Models.API
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Live data</title>
</head>
<body>
<div><h3>Data: <h3></div>
<div class="APIDataResult" id="APIDataResult>@Html.DisplayFor(modelItem => model.APIdata)</div>
<script>
var connection = new signalR.HubConnectionBuilder()
.withUrl('/APIHub')
.build();
connection.on({ });
connection.start( )
</script>
</body>
</html>
如果您决定从控制器执行此操作,这里有一个示例向您展示如何操作。在此示例中,控制器每 1 秒向所有客户端广播一个人性化的字符串。人性化的字符串将包含互联网存在的时间长度。下面的一些代码对 DateTime 等使用了 fluent API 所以不要让你感到困惑。思路还是一样。
public class UptimeHub : Hub
{
}
public class BackgroundUptimeServerTimer : IRegisteredObject
{
private readonly DateTime _internetBirthDate = On.October.The29th.In(1969);
private readonly IHubContext _uptimeHub;
private Timer _timer;
public BackgroundUptimeServerTimer()
{
_uptimeHub = GlobalHost.ConnectionManager.GetHubContext<UptimeHub>();
StartTimer();
}
private void StartTimer()
{
var delayStartby = 2.Seconds();
var repeatEvery = 1.Seconds();
_timer = new Timer(BroadcastUptimeToClients, null, delayStartby, repeatEvery);
}
private void BroadcastUptimeToClients(object state)
{
TimeSpan uptime = DateTime.Now - _internetBirthDate;
_uptimeHub.Clients.All.internetUpTime(uptime.Humanize(5));
}
public void Stop(bool immediate)
{
_timer.Dispose();
HostingEnvironment.UnregisterObject(this);
}
}
我从一篇文章中借用了这段代码,完整的说明可用here。不要忘记按照文章中的说明注册 BackgroundUptimeServerTimer
。
我有 REST API,每隔几分钟就会 return 新数据。如何在不让用户每次都刷新浏览器的情况下显示新数据? 这是我目前所拥有的。
AppController.cs
public IActionResult Index()
{
string[] day = {"Mon", "Tue", "Wed", "Thu", "Fri"};
List<API> results = new List<API>();
for (var i = 0; i < day.Length; i++)
{
var client = new RestClient("https://api.example.com/values/d=" + day[i]);
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("accept", "application/json; charset=utf-8");
IRestResponse response = client.Execute(request);
var responseContent = response.Content;
results.Add(new JavaScriptSerializer().Deserialize<API>(responseContent));
}
return View(results);
}
APIHub.cs
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace SignalRAPI.Hubs
{
public class APIHub : Hub
{
public async Task SendData( )
{
await Clients.All.SendAsync( );
}
}
}
index.cshtml
@model Site.Models.API
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Live data</title>
</head>
<body>
<div><h3>Data: <h3></div>
<div class="APIDataResult" id="APIDataResult>@Html.DisplayFor(modelItem => model.APIdata)</div>
<script>
var connection = new signalR.HubConnectionBuilder()
.withUrl('/APIHub')
.build();
connection.on({ });
connection.start( )
</script>
</body>
</html>
如果您决定从控制器执行此操作,这里有一个示例向您展示如何操作。在此示例中,控制器每 1 秒向所有客户端广播一个人性化的字符串。人性化的字符串将包含互联网存在的时间长度。下面的一些代码对 DateTime 等使用了 fluent API 所以不要让你感到困惑。思路还是一样。
public class UptimeHub : Hub
{
}
public class BackgroundUptimeServerTimer : IRegisteredObject
{
private readonly DateTime _internetBirthDate = On.October.The29th.In(1969);
private readonly IHubContext _uptimeHub;
private Timer _timer;
public BackgroundUptimeServerTimer()
{
_uptimeHub = GlobalHost.ConnectionManager.GetHubContext<UptimeHub>();
StartTimer();
}
private void StartTimer()
{
var delayStartby = 2.Seconds();
var repeatEvery = 1.Seconds();
_timer = new Timer(BroadcastUptimeToClients, null, delayStartby, repeatEvery);
}
private void BroadcastUptimeToClients(object state)
{
TimeSpan uptime = DateTime.Now - _internetBirthDate;
_uptimeHub.Clients.All.internetUpTime(uptime.Humanize(5));
}
public void Stop(bool immediate)
{
_timer.Dispose();
HostingEnvironment.UnregisterObject(this);
}
}
我从一篇文章中借用了这段代码,完整的说明可用here。不要忘记按照文章中的说明注册 BackgroundUptimeServerTimer
。