c# - 从 .Net 后端更新 React 前端
问题描述
我最近正在接近 React,我想知道如何从我的 ASP.NET 后端向所有前端发送一些更新,但首先让我解释一下自己。
我正在将一些输入从一个前端发送到后端。仅供参考,这是我的做法:
前端
async SendInput(data) {
await fetch('Status/ChangeState', {
method: 'post',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
}
后端
[ApiController]
[Route("[controller]")]
public class StatusController : Controller
{
[HttpPost("ChangeState")]
public void ChangeState([FromBody] short i)
{
//Do stuff here
}
}
现在我需要的是在其中一个更改此“状态”时保持所有已连接用户变量的更新。
我的第一个想法是使用 向后端重复发送 POST 或 GET 请求setInterval()
,但即使用户不多,我仍然更喜欢长轮询或服务器发送事件之类的方法。
一个好的推荐方法是什么?如果可能的话,包括一个例子。
解决方案
在我看来,用于长轮询的最简单的状态管理器可以使用 TaskCompletionSource 创建。控制器使用 await 等待状态更改,并将结果作为 ActionResult 发送。客户端收到数据后立即打开与该控制器的连接。
但是,我只会将此实现用于非常小的项目,并且更多地用作说明性示例。对于较大的项目,可以使用 SignalR。
/// <summary>
/// Class for your state properties.
/// </summary>
public class State
{
public string MyStateField1 { get; set; } = string.Empty;
public string MyStateField2 { get; set; } = string.Empty;
}
/// <summary>
/// StateManager
/// Register with
/// services.AddSingleton<StateManager<State>>();
/// in ConfigureServices().
/// </summary>
/// <typeparam name="T">Type of the managed state class.</typeparam>
public class StateManager<T> where T : new()
{
private readonly T _state;
private TaskCompletionSource<T> _taskCompletition = new TaskCompletionSource<T>();
private readonly object _taskCompletitionLock = new object();
public StateManager()
{
_state = new T();
}
public void ChangeState(Action<T> updateFunction)
{
lock (_taskCompletitionLock)
{
updateFunction(_state);
_taskCompletition.SetResult(_state);
_taskCompletition = new TaskCompletionSource<T>();
}
}
public Task<T> GetChangedState() => _taskCompletition.Task;
}
在 Startup.ConfigureServices 中注册:
services.AddSingleton<StateManager<State>>();
用法(在您的控制器中):
public async Task<IActionResult> StateMonitor()
{
var newState = await _stateManager.GetChangedState();
return Ok(newState);
}
public async Task<IActionResult> SetNewState()
{
_stateManager.ChangeState(state => state.MyStateField1 = "My changed State");
return NoContentResult();
}
推荐阅读
- ruby-on-rails - 为什么在 Rails 上运行系统测试时出现错误“未定义的方法 `expect'”?
- javascript - 自定义文本编辑器
- fetch-api - 在 fetch api 的 catch 块中重新抛出错误时未触发 web worker onerror 事件处理程序
- kubernetes - 如何获取openshift中任何持久卷的消耗存储百分比?
- r - 如何在 ggplot2 中每小时绘制一次 Posix 数据?
- angular - 如何保护来自 Angular 应用程序的 Azure blob 容器数据?
- r - 如何摆脱R中变量中的括号?
- apple-developer - 启用作为主要 App ID 选项在使用 Apple 登录 - Apple ID 配置中被禁用
- jsf - Primefaces selectCheckboxMenu 无法正常工作
- kubernetes - Kubernetes 中 Consul 服务 TTL 健康检查的替代方案