我希望ASPNetCore2.0 webapp能够使用SignalR向特定用户发送通知。我想从另一个控制器的操作中调用hub的方法(而不是客户端的JS调用)。
据我所知,这不是SignalR的用途,但我发现很多用户都有同样的愿望'还有一些解决方案。 我已经检查了几个建议的解决方案,但最简单和更清晰的似乎是这篇文章的接受答案:Get Hub Context in SignalR Core from within another object。
所以我试了一下,我没有任何错误。服务器的输出没有错误,浏览器的控制台和网络选项卡也是如此(我使用的是Chrome)。调试时,流程顺畅,程序完全按照应有的方式执行...除非用户没有收到任何通知......
你们有没有发现这个问题?
我创建了一个包含集线器共享方法的类:
using Microsoft.AspNetCore.SignalR;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace WebApp.Hubs
{
public class HubMethods
{
private readonly IHubContext<PostsHub> _hubContext;
public HubMethods(IHubContext<PostsHub> hubContext)
{
_hubContext = hubContext;
}
public async Task Notify(string postId, string sender, List<string> users)
{
await _hubContext.Clients.Users(users).SendAsync("Notify", sender, postId);
}
}
}
然后我创建了一个集线器:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.SignalR;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace WebApp.Hubs
{
[Authorize]
public class PostsHub : Hub
{
private HubMethods _hubMethods;
public PostsHub(HubMethods hubMethods)
{
_hubMethods = hubMethods;
}
public async Task Notify(string postId, string sender, List<string> users)
{
await _hubMethods.Notify(postId, sender, users);
}
}
}
将这些位添加到Startup的ConfigureServices方法:
[...]// Services before these...
services.AddSignalR();
services.AddScoped<HubMethods>();
services.AddMvc();
启动配置方法:
app.UseSignalR(routes =>
{
routes.MapHub<PostsHub>("/postshub");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
然后这些线到视图:
<script src="~/lib/signalr/signalr.js"></script>
@await Html.PartialAsync("_NotifyScriptsPartial")
这是&#34; _NotifyScriptsPartial.cshtml&#34;:
<script>
var connection = new signalR.HubConnectionBuilder().withUrl('/PostsHub').build();
connection.on('Notify', function (sender, postId) {
var post = postId;
var sentBy = sender;
var content = '<a href=\'#\' class=\'close\' data-dismiss=\'alert\' aria-label=\'close\'>×</a>' +
'You just received a new comment from <strong>' +
sentBy + '</strong>. Click <a href = \'#\' class=\'alert-link\' >here</a> to view the post.'
var alert = document.createElement('div');
alert.classList.add('alert', 'alert-info', 'alert-dismissible');
alert.html(content);
document.getElementById('pageContent').appendChild(alert);
});
</script>
最后,在应该发送通知的控制器中,我添加了这些:
public class PostsController : Controller
{
private readonly HubMethods _hubMethods;
public PostsController(HubMethods hubMethods)
{
_hubMethods = hubMethods;
}
// POST: Create a new post
[Authorize]
[HttpPost]
public async Task<IActionResult> Create(DetailsModel model, List<string> readers)
{
if (ModelState.IsValid)
{
// Do stuff here... including creating the newPostId, userId and receipients variables used below
await _hubMethods.Notify(newPostId, userId, receipients);
// Do more stuff and eventually...
return View();
}
}
}
有什么想法吗?
答案 0 :(得分:0)
在Asp.Net Core 2.1中,我可以像这样使用集线器,它可以解决我的问题,而且您在控制器中也使用了这样的集线器。希望对您有所帮助。
SortDescription
我可以从浏览器的控制台获取“数据”文本。如果您在项目中使用jQuery,请在DataContext
之间添加这些代码,因为您试图加载部分html,而我认为您的代码需要在ready()事件之后运行。对不起,如果我误会了你。