.Net Core MVC + Vue + SignalR 实现 后端数据主动推送到前端
1. 安装 Microsoft.AspNetCore.SignalR
2. 配置 SignalR 服务
public class RandomNumberHub : Hub
{
/// <summary>
/// 前端推送到后端
/// </summary>
public async Task SendEvent(string number)
{
await Clients.All.SendAsync("ReceiveEvent", number);
}
}
public class RandomNumberService : BackgroundService
{
private readonly IHubContext<RandomNumberHub> _hubContext;
public RandomNumberService(IHubContext<RandomNumberHub> hubContext)
{
_hubContext = hubContext;
}
/// <summary>
/// 后端推送到前端
/// </summary>
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var random = new Random();
while (!stoppingToken.IsCancellationRequested)
{
var randomNumber = random.Next(1, 100).ToString();
await _hubContext.Clients.All.SendAsync("ReceiveEvent", randomNumber);
await Task.Delay(5000, stoppingToken);
}
}
}
3. 前端界面
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"]</title>
<script src="~/js/vue.global.js"></script> <script src="~/js/signalr.min.js"></script> <style> .chart-container { margin-top: 20px; padding: 20px; border: 1px solid #ccc; border-radius: 5px; max-width: 400px; } h3 { color: #333; } p { font-size: 16px; } </style> </head> <body> <div id="app"> <div class="chart-container"> <button @@click="sendNumber">推送数据</button> <h3>随机数显示</h3> <p v-if="randomNumber">最新随机数: {{ randomNumber }}</p> </div> </div> <script> const { createApp } = Vue; createApp({ data() { return { randomNumber: null, // 存储随机数 connection: null // 存储 SignalR 连接 }; }, methods: { initSignalR() { // 初始化 SignalR 连接 const connection = new signalR.HubConnectionBuilder().withUrl("/HubUrl").withAutomaticReconnect().build(); // 监听 ReceiveRandomNumber 事件 connection.on("ReceiveEvent", (number) => { this.randomNumber = number; //alert(`接收到随机数: ${number}`); // 使用 alert 显示 }); // 连接错误处理 connection.onclose((error) => { console.error("SignalR 连接断开: ", error); this.randomNumber = null; alert("SignalR 连接断开,正在尝试重连..."); }); // 启动连接 connection.start().then(() => console.log("SignalR Connected!")).catch(err => { console.error("SignalR Connection Error: ", err); alert("无法连接到 SignalR,请检查后端服务"); }); // 存储连接 this.connection = connection; }, sendNumber() { const number = Math.floor(Math.random() * 100).toString(); this.connection.invoke("SendEvent", number) .then(() => console.log("Number sent to server!")) .catch(err => console.error("Error sending number: ", err)); } }, mounted() { this.initSignalR(); // 组件挂载时初始化 SignalR }, beforeUnmount() { if (this.connection) { this.connection.stop(); // 组件销毁时断开 SignalR } } }).mount('#app'); </script> </body> </html>
4. 配置Program启动项
public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddSignalR(); builder.Services.AddHostedService<RandomNumberService>(); builder.Services.AddCors(options => { options.AddPolicy("AllowAll", builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); }); }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseRouting(); app.UseCors("AllowAll"); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapHub<RandomNumberHub>("/HubUrl"); }); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.Run(); }
完事:


浙公网安备 33010602011771号