Via*_*lav 5 dependency-injection signalr asp.net-core
我完全按照 MS 规则定义我的强类型 SignalR 集线器
public class OutputMessages : Hub<IOutputMessages>
{...}
Run Code Online (Sandbox Code Playgroud)
比用同样的方式将我的 SignalR hub 注入到控制器中
public class ApplicationAPIController : ControllerBase
{
public ApplicationAPIController(IHubContext<OutputMessages, IOutputMessages> _outputMessages)
{...}
}
Run Code Online (Sandbox Code Playgroud)
在启动中我将 SignalR 服务添加为
services.AddSignalR()
.AddHubOptions<OutputMessages>(options =>
{
options.EnableDetailedErrors = true;
})
Run Code Online (Sandbox Code Playgroud)
并定义端点
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<OutputMessages>("/OutputMessages", options =>
{
options.Transports =
HttpTransportType.WebSockets |
HttpTransportType.LongPolling;
});
});
Run Code Online (Sandbox Code Playgroud)
看起来不错?是的。而且编译也不错。但在运行时我收到
fail: Microsoft.AspNetCore.SignalR.HubConnectionHandler[1]
Error when dispatching 'OnConnectedAsync' on hub.
System.InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.Hub`1[IOutputMessages]' while attempting to activate 'OutputMessages'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.SignalR.Internal.DefaultHubActivator`1.Create()
at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnConnectedAsync(HubConnectionContext connection)
at Microsoft.AspNetCore.SignalR.Internal.DefaultHubDispatcher`1.OnConnectedAsync(HubConnectionContext connection)
at Microsoft.AspNetCore.SignalR.HubConnectionHandler`1.RunHubAsync(HubConnectionContext connection)
dbug: Microsoft.AspNetCore.SignalR.HubConnectionHandler[6]
OnConnectedAsync ending.
Run Code Online (Sandbox Code Playgroud)
最后我找到了解决方案
这是我的强类型集线器定义
public class OutputMessages : Hub<IOutputMessages>
{
public static readonly Dictionary<string, string> ConnectedUserList = new Dictionary<string, string>(1024);
private readonly IHubContext<OutputMessages,IOutputMessages> _hubContext;
private readonly ApplicationDbContext _db;
private readonly ILogger<OutputMessages> _logger;
public OutputMessages(IHubContext<OutputMessages, IOutputMessages> hubContext, ILogger<OutputMessages> logger, ApplicationDbContext dbContext)
{
_hubContext = hubContext;
_db = dbContext;
_logger = logger;
}
....
public async Task AdminMessages2(string userId, string message, bool consoleOnly)
{
string uname = await Username(userId);
await _hubContext.Clients.All.AdminMessages2(userId, "API: " + uname + " " + message, consoleOnly);
}
[ResponseCache(VaryByHeader = "id", Duration = 36000, Location = ResponseCacheLocation.Any)]
public async Task<string> Username(string id)
{
ApplicationUser user = null;
await Task.Run(() => user = _db.Users.Find(id));
return user.UserName;
}
public override async Task OnConnectedAsync()
{
string JWT = Context.GetHttpContext().Request.Headers["Authorization"];
string ValidUserID = UserHelpers.ValidateJWT(JWT);
if (ValidUserID != null)
{
_logger.LogInformation($"User {ValidUserID} connected to {this.GetType().Name} hub");
if (ConnectedUserList.Any(x => x.Key == ValidUserID))
{
ConnectedUserList.Remove(ValidUserID);
}
ConnectedUserList.Add(ValidUserID, Context.ConnectionId);
}
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(System.Exception exception)
{
var JWT = Context.GetHttpContext().Request.Headers["Authorization"];
string ValidUserID = UserHelpers.ValidateJWT(JWT);
if (ValidUserID != null)
{
_logger.LogInformation($"User {ValidUserID} disconnected from {this.GetType().Name} hub");
if (ConnectedUserList.Any(x => x.Key == ValidUserID))
{
ConnectedUserList.Remove(ValidUserID);
}
ConnectedUserList.Add(ValidUserID, Context.ConnectionId);
}
await base.OnDisconnectedAsync(exception);
}
}
Run Code Online (Sandbox Code Playgroud)
这是控制器的注入集线器
public class ApplicationAPIController : ControllerBase
{
public ApplicationAPIController(ILogger<ApplicationAPIController> logger, ApplicationDbContext dbContext, IConfiguration Configuration, CoreObjectDumper.CoreObjectDumper dump, IHubContext<OutputMessages, IOutputMessages> _outputMessages)
{
...
Run Code Online (Sandbox Code Playgroud)
StartUp 中 SignalR 服务的定义未更改。问题是从类而不是接口创建 Hub,并且 Hub 构造函数必须完全是 IHubContext<OutputMessages,IOutputMessages>
| 归档时间: |
|
| 查看次数: |
8928 次 |
| 最近记录: |