在 ASP.NET Core 中使用 SignalR
2017-10-30 15:28
1186 查看
介绍
SignalR 是一个用于实现实时网站的 Microsoft .NET 库。它使用多种技术来实现服务器与客户端间的双向通信,服务器可以随时将消息推送到连接的客户端。它现在可在 ASP.NET Core 预发行版本中使用(译者:根据原文的发布时间)。我已经介绍过几次 SignalR 了。
安装
您将需要安装 Microsoft.AspNetCore.SignalR.Client 和 Microsoft.AspNetCore.SignalR Nuget 预发行包。此外,您将需要 NPM(Node 包管理器)。安装 NPM 后,您需要获取 @aspnet/signalr-client 包,之后您需要从 node_modules@aspnet\signalr-client\dist\browser 文件夹中 获取 signalr-client-1.0.0-alpha1-final.js 文件(版本可能不同) ,并将其放置在 wwwroot 文件夹下,以便您可以从页面引用到它。接下来,我们需要在使用之前在 ConfigureServices 中注册所需的服务:
services.AddSignalR();
我们将实现一个简单的聊天客户端,因此将在 Configure 方法中注册一个 ChatHub:
app.UseSignalR(routes => { routes.MapHub<ChatHub>("chat"); });
注意:UseSignalR 必须在 UseMvc 之前调用!
如果你有不同的端点,可以为任意数量的 hub 执行此操作。
在您的视图或布局文件中,添加对 signalr-client-1.0.0-alpha1-final.js 文件的引用:
<script src="libs/signalr-client/signalr-client-1.0.0-alpha1-final.js"></script>
实现 Hub
该 hub 是一个继承了 Hub 的类。您可在其中添加 JavaScript 可能调用到的方法。我们将实现一个 chat hub::public class ChatHub : Hub { public async Task Send(string message) { await this.Clients.All.InvokeAsync("Send", message); } }
如你所见,我们有一个方法(Send),在这个例子中,它采用单个参数(message)。您不需要在广播调用(InvokeAsync)上传递相同的参数,可以发送任何您想要的。
回到客户端部分,在引用 SignalR JavaScript 文件后添加此代码:
<script> var transportType = signalR.TransportType.WebSockets; //can also be ServerSentEvents or LongPolling var logger = new signalR.ConsoleLogger(signalR.LogLevel.Information); var chatHub = new signalR.HttpConnection(`http://${document.location.host}/chat`, { transport: transportType, logger: logger }); var chatConnection = new signalR.HubConnection(chatHub, logger); chatConnection.onClosed = e => { console.log('connection closed'); }; chatConnection.on('Send', (message) => { console.log('received message'); }); chatConnection.start().catch(err => { console.log('connection error'); }); function send(message) { chatConnection.invoke('Send', message); } </script>
请注意:
创建指向当前 URL 的连接添加了 chat 后缀,这与在 MapHub 中注册的一致
它使用特定的传输进行初始化(本例中是 WebSockets),但这不是必需的,也就是说,您可以让 SignalR 自己采用合适的方式。对于某些操作系统(如 Windows 7),您可能无法使用 WebSockets,因此您必须选择 LongPolling 或 ServerSentEvents
需要通过调用 start 来初始化连接
有一个 Send 方法的 handler,它与 ChatHub 的 Send 方法有相同的单个参数(message)
所以,每当有人访问此页面并调用 JavaScript send函数时,它将调用 ChatHub 类上的 Send 方法。 该类基本上会向所有连接的客户端(Clients.All)广播此消息。 也可以将消息发送到特定的组:
await this.Clients.Group("groupName").InvokeAsync("Send", message);
或特定客户端:
await this.Clients.Client("id").InvokeAsync("Send", message);
如果使用身份验证,您可以添加一个由连接 ID 和 ClaimPrincipal 标识的用户,如下所示:
public override Task OnConnectedAsync() { this.Groups.AddAsync(this.Context.ConnectionId, "groupName"); return base.OnConnectedAsync(); }
是的,OnConnectedAsync 在新用户连接时将被调用。当有人断开连接时,OnDisconnectedAsync 将被调用:
public override Task OnDisconnectedAsync(Exception exception) { return base.OnDisconnectedAsync(exception); }
如果在断开连接时发生一些异常,则 exception 参数将为非空值。
只有当前用户进行身份验证时 Context 属性才会提供 ConnectionId 和 User 两个属性。ConnectionId 始终被设置为同一个用户,不会改变。
另一个例子,假设你想通过定时器 hub 将定时器 tick 发送到所有连接的客户端。 您可以在 Configure 方法中执行此操作:
TimerCallback callback = (x) => { var hub = serviceProvider.GetService<IHubContext<TimerHub>>(); hub.Clients.All.InvokeAsync("Notify", DateTime.Now); }; var timer = new Timer(callback); timer.Change(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(10));
我们启动了一个 Timer,从那里我们得到了一个定时器 hub 的引用,并使用当前时间戳调用其 Notify 方法。TimerHub 类只是这样:
public class TimerHub : Hub { }
请注意,此类没有公共方法,因为它不是由 JavaScript 调用,它仅用于从外部广播消息(Timer 回调)。
将消息发送到 Hub
最后,还可以将消息从外部发送到 hub。当使用控制器时,您需要注入一个 IHubContext 实例,您可以从中发送消息到 hub,然后将其适当地广播:private readonly IHubContext<ChatHub> _context; [HttpGet("Send/{message}")] public IActionResult Send(string message) { //for everyone this._context.Clients.All.InvokeAsync("Send", message); //for a single group this._context.Clients.Group("groupName").InvokeAsync("Send", message); //for a single client this._context.Clients.Client("id").InvokeAsync("Send", message); return this.Ok(); }
请注意,这与访问 ChatHub 类不同,您无法简单实现,需要通过 chat hub 的连接才行。
结论
SignalR 尚未发布,仍可能会发生一些变化。在以后的文章中,我将更详细地介绍 SignalR,包括其可扩展性机制和一些更高级的使用场景。敬请期待!相关文章推荐
- 在ASP.NET Core下使用SignalR技术
- 详解在ASP.NET Core下使用SignalR技术
- 在ASP.NET Core下使用SignalR技术
- 在ASP.NET CORE 2.0使用SignalR技术
- 在ASP.NET CORE 2.0使用SignalR技术
- ASP.NET Core的实时库: SignalR简介及使用
- ASP.NET Core SignalR 中使用 MessagePack 序列化
- ASP.NET Core使用Razor页面
- Linux使用Jexus托管Asp.Net Core应用程序
- ASP.NET Core 2.0 使用支付宝PC网站支付
- ASP.NET Core Razor 页面使用教程
- ASP.NET Core中使用xUnit进行单元测试
- 开始使用ABP.CORE模板 (ASP.NET Core with Angular)
- 在ASP.NET Core中使用Angular2,以及与Angular2的Token base身份认证
- ASP.NET Core开发-MVC 使用dotnet 命令创建Controller和View
- ASP.NET Core 使用Cookie验证身份
- ASP.NET Core使用NLog记录日志到Microsoft Sql Server
- 关于ASP.NET SignalR的Group使用
- 【译】使用Jwt身份认证保护 Asp.Net Core Web Api
- ASP.NET Core2使用Autofac实现IOC依赖注入竟然能如此的优雅简便