添加SignalR推送官方文档:
https://docs.microsoft.com/zh-cn/aspnet/core/signalr/groups?view=aspnetcore-5.0
项目安装Microsoft.AspNetCore.SignalR包
配置集线器类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
namespace WebNetCore5_Img_Storage.Handler
{
//继承IUserIdProvider用于告诉SignalR连接用谁来绑定用户id
public class GetUserId : IUserIdProvider
{
string IUserIdProvider.GetUserId(HubConnectionContext connection)
{
//获取当前登录用户id
string userid = connection.GetHttpContext().Session.GetString("user_id");
return userid;
}
}
public class ChatHub : Hub
{
public async Task SendMessage(string user, string message)
{
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
//特定用户推送消息
public async Task SendPrivateMessage(string user, string message)
{
await Clients.User(user).SendAsync("ReceiveMessage", message);
}
}
}
C#推送代码
public class FileUploadController : BaseController
{
private readonly IHubContext<ChatHub> hubContext;
public FileUploadController(IHubContext<ChatHub> _hubContext)
{
hubContext = _hubContext;
}
public async Task<ActionResult> UploadBigFile(IFormFile file)
{
//当前登录用户id
string loginUserId=Current.Id;
//后台上传进度
decimal process = Math.Round((decimal)fileNo * 100 / total_minio_file_count, 2);
//推送消息到前端
hubContext.Clients.User(loginUserId).SendAsync("ReceiveMessage", loginUserId, process);
}
配置启动类注册IUserIdProvider的实例
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//解决中文输出后被编码了
services.Configure<Microsoft.Extensions.WebEncoders.WebEncoderOptions>(options =>
{
options.TextEncoderSettings = new System.Text.Encodings.Web.TextEncoderSettings(System.Text.Unicode.UnicodeRanges.All);
});
//services.AddControllersWithViews();
//添加全局筛选器:
services.AddControllersWithViews(options =>
{
options.Filters.Add(typeof(CustomExceptionFilter));
})
//自定义格式化json使用Newtonsoft.Json
.AddNewtonsoftJson();
//services.addNew
services.AddRazorPages();
//session配置缓存组件依赖,分布式缓存
//services.AddDistributedMemoryCache();
//会话存活时间,单位(秒)
int sessionTime = 0;
int.TryParse(MyConfigReader.GetConfigValue("session_live_time"), out sessionTime);
if (sessionTime == 0)
{
sessionTime = 7200;
}
services.AddSession(options =>
{
//设置cookie名称
//options.Cookie.Name = ".AspNetCore.Session";
//会话滑动过期时间,距下次访问最小时间,超过则session失效
options.IdleTimeout = TimeSpan.FromSeconds(sessionTime);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
//业务层注入
//services.AddScoped<IImgBLL, ImgBLLImpl>();
string path = AppDomain.CurrentDomain.BaseDirectory;
Assembly bll_impl = Assembly.LoadFrom(path + "WebNetCore5_Img_Storage.BLL.dll");
Assembly bll_interface = Assembly.LoadFrom(path + "WebNetCore5_Img_Storage.IBLL.dll");
var typesInterface = bll_interface.GetTypes();
var typesImpl = bll_impl.GetTypes();
foreach (var item in typesInterface)
{
var name = item.Name.Substring(1);
string implBLLImpName = name + "Impl";
var impl = typesImpl.FirstOrDefault(w => w.Name.Equals(implBLLImpName));
if (impl != null)
{
//services.AddTransient(item, impl);
//services.AddSingleton(item, impl);
services.AddScoped(item, impl);
}
}
//数据层注册
Assembly dalAssemblys = Assembly.LoadFrom(path + "WebNetCore5_Img_Storage.DAL.dll");
Assembly dalInterface = Assembly.LoadFrom(path + "WebNetCore5_Img_Storage.IDAL.dll");
var dalTypesImpl = dalAssemblys.GetTypes();
var dalTypesInterface = dalInterface.GetTypes();
foreach (var item in dalTypesInterface)
{
var name = item.Name.Substring(1);
string implDalName = name + "Impl";
var impl = dalTypesImpl.FirstOrDefault(w => w.Name.Equals(implDalName));
if (impl != null)
{
//services.AddTransient(item, impl);
services.AddScoped(item, impl);
}
}
services.AddMvcCore();
//用户IUserIdProvider实例注册
services.AddScoped<Microsoft.AspNetCore.SignalR.IUserIdProvider, GetUserId>();
//SignalR添加到服务
services.AddSignalR();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions()
{
//不限制content-type下载
ServeUnknownFileTypes = true,
配置的虚拟路径映射
//RequestPath = "/local",
物理地址
//FileProvider = new Microsoft.Extensions.FileProviders.PhysicalFileProvider("D:\\Work\\西南油气田图库系统\\WebNetCore5_Img_Storage\\WebNetCore5_Img_Storage\\bin\\Debug\\net5.0"),
});
app.UseRouting();
//app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
//app.UseResponseCaching();
//app.UseResponseCompression();
//用MVC模式, 针对services的services.AddControllersWithViews();
app.UseEndpoints(endpoints =>
{
//endpoints.MapDefaultControllerRoute();
endpoints.MapRazorPages();
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapHub<ChatHub>("/chathub");
});
前端界面js代码
<script src="~/lib/microsoft/signalr/dist/browser/signalr.min.js"></script>
//signalR推送消息,用于显示后台实时处理进度
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
connection.on("ReceiveMessage", function (user, message) {
console.log("user=" + user + ",message=" + message);
//后台上传视频到文件系统进度值
$("#back_process_value").html(message+"%");
});
connection.start().then(function () {
console.log("signalR推送连接成功");
}).catch(function (err) {
console.error("signalR推送连接异常");
return console.error(err.toString());
});
//document.getElementById("sendButton").addEventListener("click", function (event) {
// var user = document.getElementById("userInput").value;
// var message = document.getElementById("messageInput").value;
// connection.invoke("SendMessage", user, message).catch(function (err) {
// return console.error(err.toString());
// });
// event.preventDefault();
//});