Page 48 - MSDN Magazine, July 2018
P. 48
Figure 3 The Hub Class That Streams Back
is, telling the server to slow down when the client isn’t processing messages fast enough).
Figure 3 presents the code for the hub.
The hub offers three methods to start, stop and operate the clock. A global variable controls the running status of the streaming, and start and stop methods set the control variable and notify back client methods as usual in a SignalR hub. The tricky part is the Tick method. The method name coincides with the name of the stream to which clients will subscribe. The method returns a chan- nel object of a given type. In the example, the type is a simple string but it can be anything more sophisticated.
Every invocation, from client to server or server to client, con- sists of one party sending an invocation message, and the other party eventually responding with a completion message that carries a result or an error. In a SignalR streaming scenario, instead, the other party responds with multiple messages, each carrying a data item, before eventually concluding the communication with a completion message. As a result, the client ends up processing multiple items even before the completion message is received.
Scaling to Multiple Instances
SignalR keeps all connection IDs in memory, meaning that the moment the application scales to multiple instances, the broadcast (but also streaming, as discussed later) is compromised as each instance would only track a portion of all connected clients. To avoid that, SignalR supports a Redis-based cache that ensures that new connections are automatically shared between instances. To enable Redis, you need the SignalR.Redis package and a call to the AddRedis method in the ConfigureServices method of the startup class, like so:
services.AddSignalR() .AddRedis("connection string");
The option parameter serves the purpose of specifying the con- nection string to the running instance of Redis.
Wrapping Up
ASP.NET Core SignalR comes with two significant changes from the non-Core version. One is the lack of automatic reconnection, which has an impact on how connect/disconnect and online user count is handled programmatically. This means that now every application has to handle connection/disconnection logic and likely has to identify the difference between a user connecting for the first time and a user reconnecting due to an error. The other change is support for data streaming. Data streaming is based on channels and at the moment only supports specific data items instead of raw streams.
Finally, my exploration of SignalR lacks one more piece, which I’ll address in a future column: authenticated users and groups.n
Dino Esposito has authored more than 20 books and 1,000 articles in his 25-year career. Author of “The Sabbatical Break,” a theatrical-style show, Esposito is busy writing software for a greener world as the digital strategist at BaxEnergy. Follow him on Twitter: @despos.
thanks to the following Microsoft expert for reviewing this article: Andrew Stanton-Nurse
public class ClockHub : Hub {
private static bool _clockRunning = false;
public void Start() {
_clockRunning = true;
Clients.All.SendAsync("clockStarted"); }
public void Stop() {
_clockRunning = false;
Clients.All.SendAsync("clockStopped"); }
public ChannelReader<string> Tick() {
var channel = Channel.CreateUnbounded<string>(); Task.Run(async() => {
while(_clockRunning) {
var time = DateTime.UtcNow.ToString("HH:mm:ss"); await channel.Writer.WriteAsync(time);
await Task.Delay(1000);
}
channel.Writer.TryComplete(); });
} }
SignalR is chat rooms. A group is created programmatically simply adding connection IDs to the group of a given name. Here’s how:
hub.Groups.AddAsync(connectionId, nameOfGroup);
Connected clients receive their data through a callback. This is only the most common technique. In ASP.NET Core SignalR, you can also use streaming.
Data Streaming
Probably the most interesting new aspect of SignalR is support for streaming. Streaming is similar to broadcasting, but it follows a slightly different model and is essentially a slightly different way of achieving the same broadcast-style communication. With SignalR streaming, the hub still needs to poll or listen for data in order to stream it back. In classic broadcast, the server tells a client method when new data is available.
The hub offers three methods to start, stop and operate the clock.
In the new streaming model, the client subscribes to a new server object of type Channel and the server—the hub, actually—yields new items as they’re captured. At the moment, there’s nothing like a true stream that flows bytes toward all the connected clients as they become available, but this model can be supported in the future. Note that the Channel type has been introduced with preview2 and is not supported in earlier builds. In earlier builds, you must use observables instead, which require a reference to the System.Reactive.Linq NuGet package. The switch between observables and the new type Channel relates to the lack of prim- itives in IObservable for working with network backpressure (that
42 msdn magazine
Cutting Edge