1、安装依赖包
添加Volo.Abp.AspNetCore.SignalRNuGet包到你的项目:
Install-Package Volo.Abp.AspNetCore.SignalR
2、添加 AbpAspNetCoreSignalRModule
到你的模块的依赖列表
在你的HOST项目或者Web项目的Module中添加对应地依赖
[DependsOn(
typeof(AbpAspNetCoreSignalRModule) //Add the new module dependency
)]
public class YourModule : AbpModule
{
}
3、编写Hub集线器
public class UserHub : AbpHub
{
private const string method = "ReceiveMessage";//客户端接受信息的方法
#region 连接和断开
/// <summary>
/// 连接
/// </summary>
/// <returns></returns>
public override async Task OnConnectedAsync()
{
Logger.LogInformation($"UserHubConnected:tenantId:{CurrentTenant.Id},UserId{_myCurrentUser.Id?.ToString()}{_myCurrentUser.UserName}Connected SignalR");
await base.OnConnectedAsync();
}
/// <summary>
/// 断开连接
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
public override async Task OnDisconnectedAsync(Exception exception)
{
Logger.LogInformation($"UserHubDisconnected:tenantId:{CurrentTenant.Id},UserId{_myCurrentUser.Id?.ToString()}{_myCurrentUser.UserName} Disconnected signalR,ExceptionMessage:{exception?.Message}");
await base.OnDisconnectedAsync(exception);
}
#endregion
/// <summary>
/// 进入模块编辑
/// </summary>
/// <param name="moduleName"></param>
/// <returns></returns>
public async Task ModuleEditStart(string moduleName)
{
await Clients.Group(moduleName).SendAsync(method, userIds);//给同组用户发送信息
await Clients.User("用户id").SendAsync(method, userIds);//给单个用户发送信息
await Clients.Users(new List<string> { "用户id1", "用户id2" }).SendAsync(method, userIds);//给多个用户发送信息
}
/// <summary>
/// 离开模块编辑
/// </summary>
/// <param name="moduleName"></param>
/// <returns></returns>
public async Task ModuleEditEnd(string moduleName)
{
await Clients.Group(moduleName).SendAsync(method, "发送信息");
}
}
只需要集成AbpHub,不需要 services.AddSignalR()
和 app.UseEndpoints(...)
,它们在 AbpAspNetCoreSignalRModule
中已经添加了.
AbpHub中还有很多abp中常用的属性,可直接在自己的Hub里使用
4、重写连接和断开加入日志
/// <summary>
/// 连接
/// </summary>
/// <returns></returns>
public override async Task OnConnectedAsync()
{
Logger.LogInformation($"UserHubConnected:tenantId:{CurrentTenant.Id},UserId{_myCurrentUser.Id?.ToString()}{_myCurrentUser.UserName}Connected SignalR");
await base.OnConnectedAsync();
}
/// <summary>
/// 断开连接
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
public override async Task OnDisconnectedAsync(Exception exception)
{
Logger.LogInformation($"UserHubDisconnected:tenantId:{CurrentTenant.Id},UserId{_myCurrentUser.Id?.ToString()}{_myCurrentUser.UserName} Disconnected signalR,ExceptionMessage:{exception?.Message}");
await base.OnDisconnectedAsync(exception);
}
5、用户认证信息
[Authorize]
public class UserHub : AbpHub
{
\\\业务代码
}
加上[Authorize]表明需要认证才可访问
对应的Host或Web需要添加token验证
Module中ConfigureServices方法添加使用 JWT 持有者中间件配置持有者令牌身份验证
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Authority = "Authority URL"; // TODO: Update URL
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) &&
(path.ToString().StartsWith("/signalr-hubs/")))
{
context.Token = accessToken;
}
return Task.CompletedTask;
}
};
});
/signalr-hubs/路径的token替换为请求中的access_token请求参数
6、客户端调用,js示例
<html>
<header>
<script src="./jquery.js"></script>
<script src="./node_modules/@microsoft/signalr/dist/browser/signalr.js"></script>
<script>
$(function () {
var token = "你的token";
var connection = new signalR.HubConnectionBuilder()
.withUrl("/user", {
accessTokenFactory: () => token
})
.withUrl("http://localhost:5107/signalr-hubs/user")//hub地址,我们的集线器是userhub对应的地址http://localhost:5107/signalr-hubs/user
.configureLogging(signalR.LogLevel.Information)//定义日志等级
.withAutomaticReconnect()//开启自动重连
.build();
//接受服务端消息
connection.on("ReceiveMessage", function (message) {
console.log("reciveUsers");
console.log(message);
});
//按钮触发集线器对应的方法ModuleEditStart
$('#btn').click(function (e) {
e.preventDefault();
connection.invoke("ModuleEditStart", "dev")
.then(function () {
console.log("send")
})
.catch(function (err) {
return console.error(err.toString());
});
});
//按钮触发集线器对应的方法ModuleEditEnd
$('#btnend').click(function (e) {
e.preventDefault();
connection.invoke("ModuleEditEnd", "dev")
.then(function () {
console.log("leave")
})
.catch(function (err) {
return console.error(err.toString());
});
});
//开始连接
connection.start().then(function (res) {
console.log("connection sucess")
console.log(res)
}).catch(function (err) {
//连接异常发送错误信息
return console.error(err.toString());
});
});
</script>
</header>
<body>
测试网页
<input id="btn" type="button" value="startEdit" />
<input id="btnend" type="button" value="endEdit" />
</body>
</html>
signalr.js安装ASP.NET Core SignalR JavaScript 客户端 | Microsoft Learn