Slide 1

Slide 1 text

Fancy Features in Asp.Net Core SignalR Vladimir Georgiev Software Development Lead @ Concep VGeorgiev.org

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Real time web apps are not fancy anymore

Slide 6

Slide 6 text

Users expect Real-Time

Slide 7

Slide 7 text

HTTP

Slide 8

Slide 8 text

HTTP

Slide 9

Slide 9 text

Long Polling & Server-Sent Events … connection close connection events

Slide 10

Slide 10 text

Web Sockets open connection close connection

Slide 11

Slide 11 text

SignalR

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

SignalR Configuration app.UseSignalR(routes => { routes.MapHub("/chatHub"); }); services.AddSignalR() Startup.cs https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr • Use Visual Studio 2017 15.8+ • Use .NET Core SDK 2.1+

Slide 14

Slide 14 text

SignalR Hub public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("receiveMessage", user, message); } } ChatHub.cs

Slide 15

Slide 15 text

Client-side Code var connection = new signalR.HubConnectionBuilder() .withUrl("/chatHub").build(); connection.on("receiveMessage", function (user, message) { // Append the message to DOM }); connection.start(); document.getElementById("sendButton").addEventListener("click", function (event) { connection.invoke("SendMessage", user, message); }); chat.js

Slide 16

Slide 16 text

JSON & MessagePack Protocols

Slide 17

Slide 17 text

JSON & MessagePack Protocols Install package Microsoft.AspNetCore.SignalR.Protocols.MessagePack services.AddSignalR().AddMessagePackProtocol(); var connection = new signalR.HubConnectionBuilder() .withHubProtocol(new signalR.protocols.msgpack.MessagePackHubProtocol()) .withUrl("/chatHub").build();

Slide 18

Slide 18 text

Inject IHubContext

Slide 19

Slide 19 text

Injecting HubContext everywhere public class ChatController : ControllerBase { private readonly IHubContext chatHub; public ChatController(IHubContext chatHub) { this.chatHub = chatHub; } [HttpGet("/Message")] public Task SendMessage(string message) { return this.chatHub.Clients.All.SendAsync("receiveMessage", "Controller", message); } }

Slide 20

Slide 20 text

Strongly-Typed Hubs

Slide 21

Slide 21 text

Dynamic & magic string calls • ASP.NET SignalR • Asp.Net Core SignalR Clients.All.broadcastMessage(name, message); Clients.All.SendAsync("receiveMessage", user, message);

Slide 22

Slide 22 text

Strongly Typed Hubs public class StronglyTypedHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.ReceiveMessage(user, message); } } public interface IChatClient { Task ReceiveMessage(string user, string message); }

Slide 23

Slide 23 text

Authentication & Authorization

Slide 24

Slide 24 text

Authentication & Authorization • Cookie authentication • Bearer token authentication [Authorize] public class ChatHub : Hub { [Authorize("MyAuthorizationPolicy")] public async Task Send(string message) { } }

Slide 25

Slide 25 text

Streaming

Slide 26

Slide 26 text

Streaming public ChannelReader ShowMeTheWords(int delay) StreamingHub.cs

Slide 27

Slide 27 text

Streaming public ChannelReader ShowMeTheWords(int delay) var channel = Channel.CreateUnbounded(); return channel.Reader; StreamingHub.cs

Slide 28

Slide 28 text

Streaming public ChannelReader ShowMeTheWords(int delay) var channel = Channel.CreateUnbounded(); return channel.Reader; await writer.WriteAsync(words[i]); writer.Complete(); StreamingHub.cs

Slide 29

Slide 29 text

Streaming private List words = { /* some words */ }; public ChannelReader ShowMeTheWords(int delay) { var channel = Channel.CreateUnbounded(); _ = WriteItemsAsync(channel.Writer, delay); return channel.Reader; } private async Task WriteItemsAsync(ChannelWriter w, int delay) { for (var i = 0; i < words.Count; i++) { await writer.WriteAsync(words[i]); await Task.Delay(delay); } writer.Complete(); } StreamingHub.cs

Slide 30

Slide 30 text

Streaming var connection = new signalR.HubConnectionBuilder() .withUrl("/streamingHub").build(); connection.start(); connection.stream("ShowMeTheWords", 750).subscribe({ next: (item) => { /* render item */ }, complete: () => { /* complete */ }, error: (err) => { /* show error */ } }); Streaming.js

Slide 31

Slide 31 text

Summary • SignalR • MessagePack • HubContext • Strongly-Typed Hubs • Authentication & Authorization • Streaming

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

Use Real-Time Vladimir Georgiev VGeorgiev.org