 Now we're moving on to Brady, who's going to talk about.NET Core development on Mac. He's going to talk about Docker. He's going to do about Azure development and some other cool stuff there. So off to Brady. Cool. All right, getting started here. So I'm Brady Gaster. I am a senior PM on the.NET team. I'm going to focus a lot of my talk today on using SignalR and Docker and Azure together. Probably focusing more on the SignalR stuff because that's my main product and what I like to talk about. That's probably what you want to talk about today too. So the first thing we'll do is kick it off with a simple what is SignalR. Essentially, SignalR is a abstraction on top of a real-time HTTP connection. It's a little weird to think about HTTP as real-time, and we've got a couple of different ways that we can do that. So go ahead and get started with the demo. So what I've done, so I have a couple of projects open. Right here, I've got a pretty simple project open that if I were to run it, what we're going to see is just a simple spaceship on the screen. The idea behind this is that I want to be able to click that spaceship and move it around the screen. So if I click it, see right now, nothing's really happening. Definitely, if I were to open it up into another browser, nothing's going to happen as well either. That's where SignalR comes in because we can actually make things happen directly inside of the page. So what I'll do is I'm going to show you how to get started with SignalR without having to even use MPM. What I'll do is I use Unpacked and I go to the Unpacked. I'll look for SignalR. I find the 3.12 release, one that we just put out. I'll click on View Raw. Now I'll copy this and I'll paste it right here into my source. Now what I'm going to do is I'm going to put double at signs here because I'm in Razor. So if I were to scroll down, you'll see that the first thing is, let me get this colorization. It's a little odd on a colorization problem. So you'll see that the first thing I do inside a JavaScript is to create a new hub connection. Now that's actually a live connection back to my SignalR hub on the server side. Talk a little bit more about hubs in a minute. But the idea here is that I just have this JavaScript code and later I'll be doing the same thing with .NET code where I'm going to have a connection from my client that reaches back and talks to a SignalR hub. If I open up the hub here, see that I've got Game Hub, and really all I have is a move ship method. What I'm going to do is I'm going to pass the Y and X coordinates over, and whenever I get that on the server side, I'm going to turn around and just send it back out to all the clients. In this case, you'll see that I'm doing clients.all.sendasync. I'm just going to basically make an async call out to all the individual clients that are connected to that hub. The point where I do that, I'm going to be handling that event here with the ship moved. So what I'll do is on the client side, I'll actually make a call here to invoke the move ship method. This will invoke on the server side, I'll turn around and then I will invoke an event, a foreign event called ship moved, and I'll pass it the X, Y coordinates that we got, and inside of my client code, you'll see right here, I've got connection.on, and I'll handle that event and do some HTML magic directly inside the client. So now that I've got that running, I've got my script tag added in here, and we've got SignalR on CDNJS coming. We have an older version out there. We have a current pull request out to the nice CDNJS folks to get it updated. But my favorite way to do it is really just using unpacked. It's pretty easy to get there. Now what I've done is you'll see that I've got my window open. I'll paste in a new browser window right here, and when I click this and I move it around, you'll see that as I move it around, it's going to be moving over there on that client as well. Now the way that works essentially is that SignalR can figure out whether I can run web sockets both in my client and on my server side, and if I can, it's going to use web sockets by default. But if it can't, it's going to figure out a way to back off and be more intelligent because it knows that I want real-time and I don't want to have to code each individual real-time capability. The way that works essentially is that at first before we had web sockets and before we had long polling and all kinds of stuff, you would make a request from your client to your server. Your server is going to say, I got your request, it's going to do a process, and then it's going to fire an event and send back everything to the client. And that's how your request response model would work under long polling, which is what you'd probably have to do way before web sockets if somebody said, I don't want to have to hit the F5 key. So once we got web sockets, you have this capability where the client can basically say, I want to make a request of the server, I want to start a real-time connection. The server says, I support web sockets, we're good, and now we're communicating in real-time, we're partying in real-time. So this is the idea behind SignalR is when we created SignalR, web sockets wasn't quite as ubiquitous as it is today. It's pretty much everywhere today. All the browsers support it, most servers support it. We support it all over Azure. So for all intents and purposes, you'll usually be running on web sockets. But what's nice is if you don't support web sockets, or you know you're going to have customers who fail to support web sockets for whatever reason, SignalR can figure out exactly what sort of transport would be the most efficient and actually back down and use it. Let me do a quick little demo of that. Now if I go over here, we're done with Unpacked, so I'll close that. So up here, I've got this Move the Ship app that you just saw me write running out in Azure. So I'll go ahead and click Browse, and feel free to move the ship around if it excites you. Now what I'll do is I'll go here and I want to show you that we are connected using SSE. So this is actually connected using ServerSendEvents and if I were to open up another browser tab and paste it in, you'll see that over SSE, as I move one around, the other one will be moving around. So that's all well and good. But what I can do over here inside of the Azure portal is go to the configuration for my app service. They're right here in the general settings, and you'll see this handy-dandy little web sockets area right here. I want to turn web sockets on. By default, web sockets are turned off whenever you create an app service, but I want to turn them on because I want to make use of the web socket transport whenever possible because it's probably going to be the most real-time-ish of all the different connections. Everything else would be, we would be using ServerSendEvents by default. If ServerSendEvents weren't there, which luckily they are by default, you would be using long polling. Now if you'll see here, somebody's moving it around. Thank you whoever's moving around. But if you see that if I were to zoom in right here, now we are connected with a web socket. All I had to do was to go into my app service settings and toggle it from off to on, and now SignalR just knows that it needs to use web sockets. So that's a great example of how SignalR can make us dizzy, because somebody's probably Chris knows it's out there. So what I'll do is I'll close that for now, and I'll leave the site running. It appears that people are having fun with it, so I'll leave that on. While I'm at my browser, I want to show you the wonderful homepage for DocsMicrosoft.com. If you're looking into learning more about SignalR, either from the perspective of doing it inside of a server-based app or in a serverless app, like we'll talk about later, you would click here on ASP.NET. You notice we have the ASP.NET Core and ASP.NET Area, for those of you still using ASP.NET Framework. A lot of great apps still running Framework out there. You click on the Core, and then you would find here real-time apps, and this is where you'll find all the relevant information about ASP.NET Core SignalR. So if you want to find out how to use the clients, like the JavaScript client or the.NET client, or if you wanted to use the native Java client, you would come out here and take a look at this. We're currently working on a C++ client as well. So folks who want to do lower-level native development, hopefully by the end of 2020, with the.NET 5 way, we'd like to ship that C++ client as well. So folks who want to do native dev could grab the C++ client and do whatever they want. So with all of that being said, I'm going to switch back over to my presentation, and what I'll show you now is this concept of client targeting using Hubs. So we talked about a SignalR Hub briefly, and we'll get a little bit more in depth with it now. But what I want to talk about is how you can actually specifically target an individual client or set of clients or in this case, a group of clients. If you wanted to send messages out to an army of different clients that happen to be out there waiting for you. So the first thing that you've already seen me do is I wanted to send a message to everyone. So I wanted to send a message to all the connected clients all at one time. So I would just use clients.all.sendasync, or sendasync, and at this point, we would actually call that method. It would call it on every single connected client that happens to be connected 1,000, 5,000 doesn't matter. All the clients will get that event at that moment. But if I wanted to target an individual set of users such as a group, like let's say I wanted to target only the folks in the Seattle group, you can actually add individual signal or connections to logical groups that are managed on the server side or if you're using Azure signal or on the service side, and then I can actually send a message to that group and only the clients that have been put into that group would actually receive those individual methods. That's good. You can actually use client targeting to get down to a pretty small group of users. But let's say you only want to target one specific user. In this case, you would say clients.user, and you would pass in a name. You could also say users and you could pass in a series of names. But in this case, I only want to send a message to Brady to myself and I only want to send a message just to me as a user, which means if I'm connected on my phone, on my laptop, on my PC, on my TV, whenever a message comes to Brady, if I'm logged in as me on all those devices, I'm going to get that message on all of those clients all at the same time. So that's kind of nice. Now, if I wanted to target one specific client, like let's say I wanted to target Brady's phone, then I could actually get what's called the signal or connection ID, and I could say a client and pass in that particular connection ID and only hit that one client so I can get very, very low level in terms of like the individual clients that I can get to. So, got one more demo here. I've got a few more demos, but this is the next one. And this one is actually where we're going to talk about client targeting. So let me zoom out, take a look at my set of projects that I have open, and I'm going to do two quick demos for you here. So in this case, I've got two projects. One of them again is a web project, and one of them is a worker project. Now, in .NET 3, we added this new worker template. You can see if I open up my worker here, open up my worker file. You'll see this is my worker class, and all it's going to do is it's going to spin. And whenever I get a message off of a queue, I'm actually using Azure Storage queues here. Whenever I get a message off of a queue, I'm going to basically run step one, and I'm going to run step two, and I'm going to run step three. And as I run these steps, I'm actually going to call the process hub client, which is my client to wrap around my signal R Hub. You can see that I'm calling update dashboard, passing it in the connection ID for the individual connection that I want to target. And then I'm actually calling right here send async, telling it which of the individual methods I want to call, and I'm actually passing it in this case, I'm just passing it one particular connection ID because I only want to run it there. And I'm passing it the step completed object, which is essentially a pretty simple model. Now the idea behind this solution is you might have a web queue worker scenario where you have a web app and somebody takes action in the web app, they submit an order, the order goes into a queue, and then there's a couple of different processes that that order would need to go through before it's actually completed. And you might want to provide your customer some sort of a visual display just like you're in step A of the process, you're in step B of the process, and so forth and so on. So you might want to be able to show your customers exactly kind of how things are running, and in this case, signal R is really helpful there. Now what I've done in this particular solution, I just want to show you this because it's a nice feature in VS for Mac. As I've actually got, you see that I've got an all profile here, and I've got web and worker because I've got two projects. What I'll show you is if I zoom in on this, I'm going to double click on my solution and you'll see that this tab's going to open up, and you'll see that I have this configurations tab, and what I can do in here is I can actually click new, we'll just call it demo, I hit create, I'll click on the demo, and now I can actually specify which projects I want to run or not run whenever I do an F5 experience from within the tool. So here you see that I've got the web and the worker both set to run, everything's good there. Now I want to make sure that my other demos aren't actually running, it looks like everything else has stopped, so that's good. Earlier I had a scenario where I tried to run on a port that was already taken, so I just want to make sure that we're not doing that here. But at this point, what I'm going to do is I'm just going to hit run, and the first thing that will happen is we're going to start up that worker process. The worker process is essentially just going to run as a background process. If you think about microservices and Kubernetes, we'll get into that later, but essentially I'm just going to have a background process that's waiting and watching a storage queue. And you'll see here that here's my web app, my web app is going to open up, and what I'll do is I'll just paste in another instance of the browser, and the idea here is that I want to show you specifically how this might be the some customer who's looking at their cart, and this would be the customer who's ready to purchase everything that's in their cart. I wouldn't want to start that process and accidentally impact some other user. So that's what's great here with me being able to use the connection ID to target an individual user. So in this case, I'll start this process, I'm passing it the connection ID, and you'll see that it's only going to run down there. It's not going to run on this top one. If I were to start the process up here and then start the process again, you'll actually see that we're going to have two different separate processes and two different timelines in terms of it actually processing everything. Now I started the second one, so it's going to go through there again. Clicked it twice. So this is an example of when you can use SignalR, specifically the SignalR client for .NET inside of say a background running a microservice like a worker project, and then you can use the JavaScript client on the HTML side to actually listen for the incoming messages. So what I'm doing at that point is I'm actually just sending messages from one client using .NET and receiving those messages from another client using JavaScript. So pretty neat way of doing things. The one thing I would also show you here, and this is a fantastic feature that I love we got in VS for Mac, I can right click my worker here and I can say add and do Docker support. And I can actually add Docker support directly to this project. You'll see that I get my Docker compose files up here, and this is pretty much the Docker file that I would write myself by hand if I actually had to do that. What that's really useful for is if I wanted to run an ASP.NET core application and to our worker application connected over a SignalR hub in something like a Kubernetes cluster, which is similar to what I have running right now. So what I'll do at this point is flip over to one more set of code that kind of demonstrates this, and what I've got is two projects again or a couple of projects here. We had a question earlier that I'm gonna try to answer right now. The question was if I wanted to do Blazor WebAssembly today inside of VS for Mac, but I have that capability. Well, you do, I've actually got one running here. So in this case, I did a.NET new from the command line according to the wonderful blog post that Daniel Roth put out recently when we shipped a preview for Blazor WebAssembly. So you see that I've got my server project and I've also got my shared project. I don't really have much in there right now. And then I've got my client project. This actually comes out of that Blazor WebAssembly project structure. Now I've got another one here. And again, this is a worker that's gonna run in the background process. And I'll show you real quickly what that worker does. There's not a lot of stuff going on in it. Essentially what I'm doing is I'm using an awesome fake data generator called Bogus. I cannot recommend it highly enough if you need to generate a lot of fake data or you want to fake your UI to make sure things are gonna look right, which is pretty much what this is gonna do here. What I'm actually doing is I'm generating a random set of names. And with each one of these names, I'm going to generate a random lat long point. And I've kind of given it like an area that I wanted to start with, essentially the area around huge sound area. So what's gonna happen is this worker's gonna run and every time it runs, it's gonna create a fake map point and then it's gonna send that map point to a signal or hub. And it's gonna pass it some information. Now what that signal or hub is simply going to do is to turn around and bubble that up into the client experience itself. Now in my case, what I've got here is if I were to expand my client project, now this is again a Blazor WebAssembly project. If I were to expand this, and I go right in here to Pages and I open up index dot razor, what you'll see is that I'm actually using the dot net client for signal or directly inside of my Blazor WebAssembly razor page code. This is great because I get all the fidelity of dot net. I don't have to do the context switching between JavaScript and dot net if I don't need to. And in this case, everything I'm doing, I'm doing directly inside of dot net code. I'm not doing any JavaScript magic whatsoever. And I'm not gonna run this locally, but what I will do is I'll show it to you running up in my Azure Kubernetes service instance. So what I can do here is I can actually click on my DevAKS bookmark that we have here. Here's the link for if anybody wants to look and you'll see here that as I forward to zoom out, you'll see that just random points are just getting generated by that worker process. And as the worker process generates those random points, it's sending a ping up to my SignalR hub, which is running in the server side of my Blazor WebAssembly solution, it's actually the server part. And then that hub is basically bouncing the message out to the dot net client in my Blazor WebAssembly client project. So at this point, we're getting messages out of the cloud we're pumping them right into this Blazor WebAssembly UI. And if I were to, pardon me, flip over here to my demo microservices, AKS cluster, and I were to flip here to monitor containers. Now these are Docker containers that I was, I created these Docker containers and wrote the Kubernetes Hound myself and published these up. I did that all from within VS for Mac. I did use of the command line to actually do the Docker publish. Looking forward to those tools coming one day soon too. If I were to click on containers here and what I wanna do is I'm going to filter on a namespace and I'm gonna filter on my bogus map namespace because that's where I happen to have this code running. And if you see this map.generator here, that's actually the background process that is pinging my SignalR hub and sending it points. You can see we've generated quite a bunch of points since we started this demo today. If I were to click on view live data, what you'll see down here in the bottom of my browser window is the outputs, the logging output of that individual worker project, just sending data up into the cloud. You can see this is just the log data and if I were to click here on the map.ui and show you the live data here, now essentially if I just go here and I hit refresh, should see there's our logs coming in because I actually made it, made a hit to that site. And if we were to again look at this one and look at the view live data, you'll see that as we have points popping into the log, we have points popping into the map. The idea behind this, the reason I wanna show you this is it's a great use case. If what you wanna have is just a screen in your team room or a dashboard that you wanna monitor forever and ever, SignalR is really, really great for those things because you can kind of set up code that will instrument out, as a process happens, you can see individually each step of it or in this case you can see dots appearing on a map. So that's the nice thing about SignalR is it's really great for adding that UI sugar and making things appear real time, which is always fantastic. Now, flip back over to my deck one more time. I wanna go here to flip that. So real quickly, another feature that we added in the recent releases of SignalR is this concept of automatic reconnection. It's one of my new favorite features and what we have some great documentation for it. Let me actually go back to docs.ms.com and I wanna show you this in the SignalR area. So I were to click here and look at our clients and right now I'll just go to the .NET client because that's where we are today. You can see over here handling a loss connection and see that we have some pretty sensible APIs, specifically in this case with automatic reconnect. If I pass, if I just call with automatic reconnect, it's gonna try maybe four or five times and the documentation points out here that we wait zero seconds to 10 and then 30 seconds and then we stop trying. So you can customize that if you want to. Now on the .NET side, you can customize that pretty easily. So I've done right here. Again, this is a similar project structure than what we saw just a moment ago. In one case, I've got my SignalR server and the idea behind that is I'm gonna run my SignalR server outside of my Blazor app, not for any particular reason, I just might wanna have something connect to it that isn't my Blazor app. So I wanna take that and split it apart and what I'll show you in that, if I were to open up startup CS, here is a handy block of code and it comes to enabling cores. Sometimes if you wanna have, Site A is gonna communicate with Site B either through your REST API or with SignalR, you're gonna have to turn on cores and this is about the least amount of cores code I could get in here and make everything work. Essentially what I'm gonna do is I'm gonna tell this app which is running on port, you see here, running on port 4000. I wanna tell this app that it can trust anything coming from port 5002. If you wanted to, you could configure that, put it in your app settings, use Azure app configuration to configure it however you want to for deployment. But the idea is you wanna enable that trust relationship because this server is going to run the hub and then this server is going to reach out and connect to it as is this client. So you wanna make sure that you're enabling cores here and in this case I'm just passing a URL, I'm gonna be going over to port 4000 to get to that sequencer hub and more on the sequencer hub later. And in this case you'll see that I've called with automatic reconnect and I've passed it an array of time spans, essentially getting longer and longer and longer each time. So what I'll do here is I'll scroll down a little bit more and I'll show you that the hub connection and this wave of with automatic reconnect love, we've also added you some new events specifically reconnecting and reconnected so that you can handle those events and customize your UI to basically tell people you can't click the button right now or you can't fill out the form or insert whatever it might be right here. But we gave folks those events so that you could have more capability in terms of being able to handle those reconnecting situations on the client side. You also have this inside of the JavaScript client too so you can do everything you'll see me do in a Blazor WebAssembly project. You can do this inside of JavaScript as well. So the first thing I'm gonna do just to kind of show you how this reconnection would work is I'm gonna run this inside of my command line first. So I'll say open in terminal here from that SignalRServer project and here's my SignalRServer and I can do .NET run. See if this guy will start up and once the SignalRServer starts up, I don't wanna click the URL because there's not gonna be any UI there. It's just gonna be my hub running in the back. But what I'll do next is I'll right click on my Blazor SignalR loves Blazor.Server project and I'm gonna say start debugging the project and what that's gonna do is it's gonna run my Blazor server, compile my Blazor WebAssembly client into it and then launch the UI. And it's just a pretty basic UI here. If I were to open up our debugging tools, I'm not gonna do any Blazor client side debugging yet but if you consider debugging tools, it's important because I want you to see how this will change and then you'll also see over here that it's trying to reconnect. So if I just stop the server, see now it says connection refused, it's trying to reconnect, there's no server to connect to so it can't but it does tell us, hey, I'm trying to reconnect, I'm trying to reconnect in a moment maybe if the server comes back online or I exit the tunnel, now we're reconnected again. So this is great because the user won't have to sit there and click refresh and you can provide cues to tell them for just a moment, we don't know how long, you might have gone into a tunnel, the application is not connected to your SignalR Hub so we're gonna do what we can to get you reconnected again. So it's just a nice way for you to be able to help your users understand what's going on in the application. So with that said, I'll go ahead and close this down and I'll stop everything else and we'll flip back over to my slides one more time and this is one thing that early on in SignalR we had a lot of questions about scaling out with SignalR and I'm gonna talk to you about why. And this is pretty much gonna be the end of our presentation on SignalR and running your .NET Core app inside of a Docker and creating your Docker containers and side of VS for Mac. So what I'll do right here is I wanna show you the scaling out for Azure Part. Now something to think about is that your Hub lives on your web server, lives on your application server. That Hub is in your server if you were to scale everything out that Hub still lives on your server. If you were to take your application and move it on to multiple servers, now you're gonna have multiple instances of your app along with multiple instances of your Hub. Bad things can happen. Here's what it would look like. So in this case, the Hubs are server bound so one client sends a message. All the clients or the different groups that are supposed to get it will receive the message. See that there's the third request coming in but what happens when you scale your SignalR application out into a server farm? This is when things get a little tricky. What'll happen is that your request will come in and it will hit the server, you will start communicating with your Hub and each client that connects to each server will only communicate with other clients that happen to be connected to that server. So what that means is you're kind of in a bad place if you wanna scale it out. Now what you can do is you can actually drop in what's called a SignalR backplane. Now in the early days of SignalR we had a couple of different options. We had a SQL server backplane. We had an Azure service bus, a service bus backplane, yeah, service bus backplane and then there was a third one, a Redis backplane. So we actually had three different backplanes and we kept thinking we needed to make this better but essentially what would happen is you send one message in, it hits your server and then they're gonna come back out to all the different servers. What we did was we created a new thing called the Azure SignalR service. Now the Azure SignalR service gives you a way to offload your ASP.NET Core SignalR hubs. So what you can do is you can create a hub, let's say you're hosting your hub in Azure App Service. You can actually put your app into Azure App Service and then you can turn on Azure SignalR service that basically will cause all the traffic that goes to web sockets that goes to your hub to go there instead of chewing up the bandwidth going back and forth to your Azure App Service. Essentially the way that works is your client reaches out and it makes a call to your ASP.NET Core app. You're gonna get pages, you're gonna talk to your hub and all that jazz. And then what will end up happening is the Azure SignalR service has a server side connection back to your hub. Very much, I think it's actually a signalR connection back to your hub and what we'll do is we'll instantiate four or five connections between your server side app and your Azure SignalR service hub. What that means is that on the server side you only have about four or five of those active connections instead of 100,000 connections. Now what also does is that frees up the HTTP traffic going to your actual front door of your web application so that that front door is not handling all of your normal HTTP one traffic and all of your web socket traffic. All of your web socket traffic basically goes over to the Azure SignalR service. The other nice thing that Azure SignalR service can give you is the concept of serverless signalR. So you can actually use Azure Functions, have a nice feature inside of them called Azure Function Bindings and you can actually apply the Azure Function Bindings for signalR service so that whenever you make a call into your Azure Function, it will call back to the signalR service and then if you have any clients that are connected to the Azure SignalR service instance, they'll get those messages. That's really helpful when you're starting to cloudify your applications and doing serverless dev and all that good stuff. In this case, you wouldn't even have to have a server side hub anywhere. You could just use the Azure SignalR service instead of having to actually craft your own hub. But if you start getting into Blazor development, what you'll see inside of the tooling is that we're giving you the opportunity to create Azure SignalR service instances whenever you're deploying your app services because we want you to have that enhanced capability of that enhanced performance. We want all of your web socket traffic going to where it should go, which is the Azure SignalR service and all of your normal ACTP traffic to go back and forth to your actual web application. That's pretty much all I have to share today. I think we have a couple of questions. My good buddy, Christos is back in the room now so I think we'll turn it over to him for a question or two. Exactly, well, thank you very much for showing us all the cool stuff there. We actually have a couple of questions but before we jump the questions, I want to give a shout out to Simone here who's actually working out on his static bike while watching the sessions, right? That's amazing, fitness and learning at the same time. Let me jump quickly to the questions. One of them is, when should I choose Azure SignalR services over hosting my own SignalR service? That's a great question. And I presume what that question might be asking is, let's say I wanted to create my own server-side application like you saw me do a couple of times here that's just running a hub. In that case, if you scale that thing out, remember you're gonna scale it out and all of your, if you connect to it, you're only connecting to it. Clients that only connect to it and send messages into it will only be hitting clients outside. The reason you would use the Azure SignalR service there is it not only gives you that back playing capability but you don't even need to write a hub. You can actually call the Azure SignalR service directly using JavaScript, Java, or any of our other clients. And we actually have a native iOS client not being built but an open source one on GitHub. So if you wanna do any like, you know, native iOS stuff, you could do that as well. And the great thing about that is you don't even have to do anything with .NET. You're not a .NET person. You don't wanna write a hub. You don't have to worry about it. You can use the service and use the service in a server-less capacity and then you can just communicate. Serverless. Serverless. I love serverless. Right. And the other question we had was, obviously, let me just close this one down. Open this one. What we do here is anything we need to consider when thinking about production scaling? There is. There are quite a few things. I don't know if I can get the screen back again. But one thing that I've also done is I've pulled up the Azure documentation. I've gone out here to the docs real quick. I'm gonna click on Azure and just show you how you can get to the Azure SignalR docs. It's currently in the web area. So I'll scroll down here to web and you'll see there's the Azure SignalR service. And if I were to click on this, what you'll see is that there's a couple of great articles in here specifically on how to scale things out. There's one here on scaling. If you wanna scale the single instance of Azure SignalR service, this is how you could do it. But what a lot of folks wanna do is they might need more than 100,000 active connections. So what you would do there is you would actually use multiple instances. And what we've seen a lot of folks do is they'll use a set of multiple instances for the Azure SignalR service. So everybody that connects to West gets put into a West group. That West group goes to the Azure SignalR service running in the West and so forth and so on. So you can actually shard things out and there's a couple of really great articles in here on disaster recovery in the same way. So you can actually set up a couple of different Azure SignalR service instances. And if a tidal wave hits a particular region and that region goes out or in certain reason here, it can go to the next one and the next one and the next one. So you can actually do disaster recovery with it as well. That's great. Tidal waves and SignalR. I think we had it all. So we're gonna take a very quick break and then we're gonna move on to ASPnet core apps in Visual Studio for Mac with Sahed Brahimi and Juan John to help us out. Thank you.