Intro to SignalR in C# Part 1 - using Blazor, WPF, best practices, and more

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
signalr is an excellent way to connect two or more clients together for real-time communication the best part is that this library is a wrapper around web standard technologies such as web sockets and long polling it just makes them easier to use that means we can even use signalr with other clients such as java or javascript in this video we're going to learn how to set up signalr and how to connect to it using web clients and desktop clients throughout the video we'll cover best practices as well as how to use this in the real world now if you don't know me my name is tim corey and it's my goal to make learning c-sharp easier i do that by providing videos here on youtube multiple times per week plus i have a weekly podcast i also provide courses on c-sharp web development and much more on imtimory.com the profits from those sales are what pays the free content here on youtube so that everyone can have a great education in c sharp not just those who can afford it in this video as with most my videos i'm going to create some source code if you'd like a copy of my source code use the link in the description all right let's go to visual studio and we're going to start by creating a new project and we're going to choose a blazer server app for this and run you we're going to say this is the blazer server what's called laser server and we're gonna say this is the blazer server um app well let's call it the um signalr app all right and we're gonna hit next dotnet six we're gonna use no authentication yes to https noaa docker hit create and we can use pretty much any of the web project types for hosting our signalr this is going to be both a host and a client now let's um actually move my my tabs to the last move to the top i prefer them up there okay so now that we have our blazer server app open let's go to the right click on properties i'm sorry right click on dependencies and say manage nuget packages and we're going to search for a new get package called microsoft.asp.cor.signalr.client that's this one right here not the core version client uses the core version if you notice down here under dependencies you'll see that it uses the core version but that it adds things to it for connecting using the from url which we'll use in uh in this demo so we're gonna use the the full client not the core version of it don't get confused by the word core there it doesn't mean dot net core these are both work with dot net core the difference is that this means just the um the basics whereas this means the full client so we're gonna choose the latest stable version and install this hit i accept and we're done and now we can start setting things up in uh in visual studio now again this is going to be a both the server and the client and we're going to follow along with um this is actually a slightly adapted version of what you're going to get right in the microsoft docs now we're going to start with that and then we'll start changing things as we go to better understand how this all works so what we're going to do is we're going to right click on the blazer server and say add new folder we'll call it hubs plural right click on hubs and say add class and we're going to call this class the chat hub this is kind of the basic standard demo that everyone does when they start building out signalr again signalr allows for real-time communication so the most obvious thing would be chatting where you can have a message that everyone can get so you you say hi everyone gets high they can reply back and back and forth you go it's a great stand-in for showing you the connectivity issues and so on however by the end of this video we will use a different hub that will not just send text over will actually be sending over information for our counter page and we'll change the counter value based upon the information we send in so we will get to doing uh new cool stuff for this not just a basic chat application which everybody does we're going to use this as a stand in to get the basics out of the way and understand what signal r is how it works now i don't like the um this namespace setup i like to have the file scope namespace so i'm going to do that but then i'm also going to right click on solution and say add edit config it always errors out like that they open it back up and it's fine go to code styles and change from block scope to file scope on namespace declarations so i'm going to change but that way a new file we create now should have this set up okay this is the chat hub we need to have a using statement here for using microsoft.asp.net core.signalr this is the newer version of signalr so there is an older version but this is the newer version of single r and again just to be clear signal r is just a wrapper around web sockets it also has full backs which are server driven events i believe it's called and then long polling are the two fallbacks so what happens is websockets it's a industry standard thing not a microsoft thing but you can connect two clients together over the web using web sockets if they both support it and then if there's a problem like maybe a there's a temporary internet glitch something like that you'd want to have a reconnect ability signalr allows you to do that so allows the setup it allows the reconnect it allows for a lot more things that it's doing that's kind of making life easier for you on the c-sharp side think of it like dapper but for connecting the clients together it's an it's a wrapper that makes life easier okay so we have our chat hub this will be the thing that we talk through where i have one uh public task called send message and in here we'll say string user and string message and we also inherit from hub there we go and this is going to return clients.all send async user message oops and we also give it a name receive message okay so what's going on here well this is the kind of like the server and so when we say hey when something calls and we'll see where we're going to call this but when something calls the send message method we're going to pass in a username and a message what are these two values anything you want to be so it could be tim and hello world it can be a guide and you know i hate goods i don't know but those two values where you pass into this method when that happens it's going to figure out which connect which clients are connected and it's going to say hey i want every client to get this message and it's going to say here's the message type receive message so this is the message type is the the type of data is coming through so this is the receive message type and here is the data that's associated with that message there's a user and the actual message itself okay so that's all it does now this implies a few things first of all we can have more than one client connected to the server and yes you can have lots of clients thousands of clients connected to the server the cool thing here just so you know is that your web server can handle thousands of connections tens of thousands potentially of connections at some point it's gonna get too large though where maybe you want to connect a hundred thousand people at once that's probably unlikely because it's at once it's not during the day different times it's at once but let's just say you did well you can offload this to signal r on azure and scale this up and allow that so if you ever did get to that point where you're like man i want to have this connectivity but i've got tens of thousands you know maybe even hundreds of thousands of connections at a time well then you can scale up to an azure azure account and scale this out now so that means multiple clients all indicates we don't have to send a message to everybody we can set to certain clients or only one client so this is just saying send to every client but again we could send it just a few and then send async just means we're gonna send we're gonna trigger this receive message on every client and pass in this data and that's going to do it asynchronously all right so that's the hub is really simple it just has one method we'll see how to add more hubs and different messages later on so that is the chat hub now we have a chat hub set up let's go to program.cs and configure this and we'll talk through the parts that we need now we need to add a using up here let's get rid of the things we don't need let's add a using for microsoft dot asp.cor dot response compression and using signal r whoops using uh blazer server dot hubs all right now we we're set to start configuring now we're not going to mess with the defaults that are already built in here but this is our section in the program.cs and if you're confused as to why there is no setting setup.cs i did a video on that this is just the not.net 6 stuff where they put setup.cs and program.cs in the same file it's all it really is so here is our services setup for our dependency injection so we're going to add one more service builder dot services not razor pages dot add response compression and we're gonna say let's set up some options and in here we're going to say options dot mime types equals response compression defaults dot mime types dot concat and we'll talk well this is in just a minute once i'm done new array and we're gonna say in here application slash octet stream make sure you spell that right okay so what are we doing here well if you're familiar web types and web servers and how they run they need to know how to process various types of data coming to them or coming out of them and so this right here says hey let's make sure that our web server has the ability to process octet stream okay so that's what this is doing and it's adding compression to it all right so it allows to add this response compression which means that the connection for signal r is very very uh very very small so that it can be as optimized as possible so it's just making sure that we configure everything to prop properly talk to our web server all right so with that being done we come down here to after our map blazer hub which by the way that's signal r map the blazer signalr hub to the default path this is blazer server which remember this blazer server kind of sits on one foot on the server side one foot on the client side where it runs server side so you can have secure code in there talk to a database and so on but yet it looks like a client-side application in that when we hit the button on the counter it increments without reloading the whole page because it uses signalr in the background to talk to a javascript library in the front end that enables that linking between our page and the backend code so we already map a blazer server hub now we're going to say app.mavhub and give our own hub which is chat hub and we give it a path so how do we connect to this what's the the url to connect to our um to our chat hub well let's call it chat hub that's pretty typical so now if we go to our website and say slash chat hub we can connect to that bla that um signal r connection now you can't just go there manually we need to use a client to go there but this will allow us to to connect to that um that location all right now let's go to our index page and here's where it's going to get a little interesting and that's because we're going to have both the the client and the server on one page and that can get confusing at times because you're saying wait you're sending a message to yourself right well yes and no because remember that a web page isn't opened by just one person so if you open a copy of this webpage and i open a copy as webpage at the same url then when i put a message in and you will see it and when you put a message in i will see it so we're going to see that first that's kind of the the standard basic demo stuff then we're going to break apart and have actual clients and actual servers so let's get rid of all the standard stuff except for the actual page directive we're gonna add a using statement at the beginning using microsoft dot asp.cor dot signalr dot client we're also going to inject using dependency injection navigation manager let's call it [Music] nav manager and implements i a sync disposable so we can actually asynchronously dispose of this we go off the page which means disconnect from our our hub now let's go down into the code so let's put a section here for at code we'll start here and say private if i can spell right private hub connection and that's nullable let's call it hub connection and we have a private list of string let's see messages equals new now this right here this is going to connect to our hub which again is on this same web server but this right here will be a list of all the messages that we get from chat so we'll be able to display that on the page and then we also have private string user input and private string message input and we could make those nullable too let's just do that strings are nullable but this right here says yes i'm acknowledging that this could have a null in it and that's okay that's the the difference there so now we have these in place let's go up here and start writing some just a little bit of of code here so we're going to say uh div start code html class equals form group basically a really ugly form that's okay [Music] label or essay user inputs at bind equals user user input and let's self close that so that's going to uh bind to this string right here and we're not using the the real like um we could be doing uh actual in um text input and all the rest the the newer blazer stuff but we're just gonna use a quick label here just to get something going um whoops we're gonna copy this and we're gonna paste it again and we're gonna say this is the message and this will be the message input like so and then we're gonna have a button with an on click equals we don't have a method for this yet we're going to say send and then we'll say we're going to have i'm following the the example on microsoft site here so we're going to do this just to see how it work or how it look disabled equals equals uh not is connected or is connected equals false notice out i'm not a big fan of the the the knot here it blends in so easily so you can also say uh equals false so if that is the case it will be disabled see this button here that's going to say hey it's disabled if we're not connected to our hub which we haven't a um is connected yet we'll get that in a minute and we have this idea once we click the button if it's not disabled it's going to send our message so we'll supply a user we'll supply a message we'll click send but only if we're connected to our hub to actually send the message all right so now down here in the code we need to write some more code protected override on initialized async which we make async task get rid of the the standard uh code there and instead we're going to connect to our hub when we we have our uninitialized async so we're going to say hub connection equals new hub connection builder and we'll do on the next line dot with url that's what the remember i said that the the core version of the nuget package we looked at didn't have this particular method on it so you have the full version uh nav manager that's the eyelet brought in with dependency injection so that's that's right up here on line three so nav manager and then we want to say to absolute uri and we give it our path to our chat hub which what we're doing here is saying hey you're the navigation manager you know what the url is for a website so just grab that url including using this path and including this path so it's localhost colon1234 whatever it is slash chat hub is what come out with and then we're going to have a with automatic reconnect and a build so what this does it creates connection to our hub and the connection is to the slash chat hub hub specifically which again if you go to program.cs right there that's our hub and it's a type chat hub so that's how we connect this is the this is the client side part of it or on the client side connecting to our hub and saying this is the hub i want to talk to this automatic reconnect here this is really cool we're going to see this when we implement the wpf client the desktop client we're going to do is we're going to take this off and show a difference but essentially what happens is if there is a problem with the connection which happens you know your internet glitches for a minute maybe you switch from uh wi-fi to cellular or maybe you know whatever it is if you need to have this constant connection which is what signalr does it keeps the constant connection open very very tiny little packets back and forth it basically just basically just pings back and forth but if that connection gets lost and you don't have this line then you've disconnected from a server you'd need to reconnect but with automatic reconnect does exactly what it says it's going to try to automatically reconnect to the server now by default you don't give it any times which i haven't then i believe it connects or tries to reconnect immediately and then after 2 seconds and 3 seconds 10 seconds and 30 seconds and so that's almost a minute where it's tried like five or six times i think five times if it doesn't connect after that then it closes the connection but at least it gives it a shot now you can change those times and say hey i want it to be every five seconds for a minute cool go for it whatever it is it will try to reconnect and find the server if you have a spotty connection that comes and goes it will reconnect all right and then bill just actually uses the hub builder and does the connection with this information and sets that connection up now we haven't started the connection yet but we've built the connection now we're going to start the connection in just a minute but first i want to capture an event first that way the event is set up before we connect to the server so hub connection on and the type is string string now how do i know it's type string string well because our chat hub string string those are the two things that are the two data types that are sent with a message so it's string string and we're going to say it's a receive message type this correctly because this is this right here it's a string but yet it corresponds to this so when when the chat hub says send all clients a receive message and you have a receive message right here this will be triggered with the two data points that are coming in are the user and the message so make sure that that it matches up then we're gonna use an anonymous type here or knowledge method and say user and just user uh message whoops i closed too early sorry user message and then arrow and let's go to the new line with um create braces so in here we're going to say var full or formatted message equals we'll just interpolation here and say first user colon space message okay so we're creating a a new string that is the combination of user and message look hold in between okay now we have this we're gonna say messages dot add formatted message remember that the the messages is a list of string which we're going to display on the page and say hey here are all the messages that we've received and then we're going to do an invoke async state has changed now what's this doing uh let's first of all put the close paren and the semicolon what's this doing right here well because the fact that this is captured on an event and we changed values that this page will need to see since it happened we need to tell blazer yeah something happened on the page you need to check for new values because otherwise it might not display those new values until something else changes on the page so what we do is we say state has changed and we're invoking that asynchronously so what this is is this is the client side this is the um the receiver of the message so this this is what captures messages from the server so the server is this send message that's all the server does really and we we initialize that on the program.cs so that's that's the whole setup for the server side for the client side we're going to listen for messages from the server on this particular of this particular type now we don't have to if we are not listening for this particular type of message we just won't get it everybody else will but we won't process it we our our connection will get it and the connection will say hey i don't have anything to do with this therefore i just ignore it it's kind of like uh click events if you don't have any wired up to them well then nothing happens now we still haven't connected to us or haven't set up the connection i'm sorry we said the connection we haven't actually connected to our server yet or our hub so await hub connection dot start async and that's a lowercase h which is why it's yell may not give me intellisense for that so we're going to start our connection we can wrap that in a try catch but i think this is fine for our demo uh but again we'll see wrapping us in a try catch in our wpf app again just for more uh safety and ensuring that it actually does start because what if the chat hub wasn't there now it should be since we're on the same web server as the hub we're actually the same project as hub but just because something should be there doesn't mean it is really there so again we'll see more about wrapping that and try catching how to do that in a in a future part of this demo so we've now got a connection open to the the server we're not done yet though we still need to have the send and it's connected so let's start with the private async task send and in here we're going to do is say if hub connection is not null meaning we have a connection then in here we're going to say await hub connection dot send a sync send message is that software and i'm gonna say user input and message input so send message notice it's a string send message if we go back up to our chat hub is the name of our method so that's the connection there this is going out to the server and saying hey trigger this message to go to everybody so broadcast this we're saying this is the method i'm going to call on the hub and i want to give you these two pieces of information which happen to be two strings both first the user and then the message this the server the hub says cool got it okay every client i want you to receive this message so here's the the type of message receive message and here's the data which was provided by this send right here which means that when we send a message we're going to trigger this method right here which is an event which is going to capture the receive message event and we're going to capture the user and the message and print them out notice this is not user input and message input it's not the things on the form it's the data we got back which means we could get this from a different version of our web page okay now let's get the is connected which i'm going to do exactly the same thing we did on the the microsoft help page just to show you is connected and say simple lambda it says hub connection ah i hate how it does that hub connection if it's not null give me the state equals hub connection state dot connected so it's saying hey is the is connected is going to be if the state is connected then yes it's connected so if the state equals connected then it's connected otherwise it does not equal that therefore it's false and lastly we want to have a public async value task of dispose async and this is remember back up here we said implements iasync disposable that interface well that interface has one method on it and that is dispose async so when this page gets closed we're going to have a this method run and we're going to say if hub connection is not no so if there is a connection no matter the state await hub connection dot dispose async it's going to close down and properly dispose of our hub connection all right we're almost there the last thing to do is go back to our html we've got the form okay so user input and the message input and the button but now below that let's let's put a horizontal rule and then below that we're going to have an unordered list and we're going to do is inside this unordered list we're going to say at for each string message in messages and then inside here we'll have a list item for each message so let's just loops over our list of messages string which is all of our messages from the chat hub where i'll loop through all of them and put them in an unordered list so just gonna show all of our messages that's it on this one page we have all the client stuff set up we have connected to the hub which we set that connection we said the event that happens when we we're going to listen for the listener for the receive message event and we set up the method to send a message to the hub and then we also handle the disposal of this page let's launch this and see an action and to do this we're actually going to launch it twice so let's launch it it comes up and i am going to just put it right like this and then let's let's copy this i'm going to create a new instance of let's do an incognito window just to show that it's definitely different and now i'm going to log in let's say this one's tim and hello world let's zoom in here a little bit on both of them so you can see a little closer hit send notice both screens say hello world and if this is joe and i can say hi tim it says on both screens okay so we've got the message on both sides and that's how signalr works there's a connection there where both screens have it now if this screen right here the incognito window was actually halfway around the world it would still work the same way as long as we're on an actual web server not localhost but this allows for real-time communication now the first and most obvious like we've done here the first most obvious thought is cool it's a chat app and that's all i can think of that it could do but there is so much more that this could do if you want to create a small interactive game in blazer where you have users connect to each other maybe not to everybody maybe just to each other you could do that and have real-time communication back and forth for moves on a board or whatever you want you could have information where maybe every blazer client is consuming a um you know values from a stock ticker or from a database maybe there's a real time charting going on where you're sending information for charts down to every blazer server client so they can all see the latest information or maybe you have an event where you create an auction and you want to show in real time what the auction value is without refreshing the page having this happen automatically uh ebay does this i believe in the last like few minutes of an auction where that that value is live the page doesn't refresh on a period it's just automatically refreshed every time that the auction value changes so they only do that in the last few minutes because it could be a real connection issue but for short periods of time that's great so there's lots of potential here with these connections so let's close out this one which will close out the connection to the server because this one has the hub and if we do that attempting to reconnect to the server we can't reconnect because there is nothing there because the actual web server's down so we're going to see more about reconnecting it's hard to show reconnects with the the web server when it's a client too because it's both the client and the server but we're going to show that with wpf in a independent client so we'll see that in in a minute but first we have to have a client to talk to so let's uh shrink these things down and we're going to right click on our solution actually let's close out our our two values here first um right click on solution and say add new project i'm going to choose wpf application and i'm going to call this our wpf client this is just a client it's not the server 2 just a client and yes.net 6 so now we have our our client and we need to then before we do anything here we need to right click on dependencies and say manage new get packages go browse microsoft.asp.cor dot signal r dot client you may say well wait asp.net core yes asp.net core because we're going to talk to a web server so therefore we the asp.net core signal signalr client this the microsoft.asp.cor.signalr that's the newer version of the newer iteration of signalr so yes install this not the core the full client and hit okay and accept and once that's done we can close out of the window and come back over here to our xaml now some of you may not like xaml i understand it's a thing but i'm going to shrink this down to 50 well that's that's a little small let's go with can we do 80 how about that so you can kind of shrink this window a little bit more um and kind of cheat here we can this is what was on my wish list and in fact earlier videos i've had on wpf i talk about my wish list of being able to pop out the xaml and have a totally different window from the designer so have this tab and this tab not connected tightly well now you can there is a little button right here that says pop out xaml so the the good people at microsoft or santa i'm not sure who listened and heard my plea and add that little button and i i love that button however it's not necessarily demo friendly because i only record on one screen even though i have three so in real life i pop this into a separate window on a separate screen but in this case i really can't do that but i can't show you both so i was going to kind of cheat and make this a little small and then come down here and i'm going to add the the font size i'm going to set to be 18 across the entire form that way we have a better visibility on our form okay the very first thing to do this is going to be a quick and dirty wpf application it's not going to be necessarily pretty so we're just going to make something that works so i'm going to set up grid.row definitions without column definition just rows row definition a a height of auto and we're going to copy this and we're going to paste it i'll paste it five times and then the last one's gonna be star instead of auto what that does is it sets up four columns they're going to have a height of auto meaning if there's nothing in them they collapse to nothing which means i could have 30 rows and only use 3 and be just fine that last one though is star which means that it's going to use every bit of the available space left which means we're going to have the blank space at the bottom of our form so that's kind of my crash course on rows inside wpf okay after that let's create a button and we'll give it a name x colon name equals open connection and spell it right there and we're gonna say this is on grid dot row 0 which by default is anyways but i like to specify it horizontal alignment equals center next row down i'm going to say padding is going to be 20 and 10 that means it's wider than it is tall the padding and margin is going to be 20 all around and let's close this out and say open connection and there's our open connection button on our form remember this form is only 80 of the actual size let me get 70. so you know it looks kind of tiny there it's actually bigger than that in real life that's the art that button we're going to use to open a connection to our server next up we're going to have a stack panel stack panel to great because we can actually just throw a bunch of things in there in this case two things and they just arrange themselves in this case we want it to be an orientation of horizontal and the grid.row is only one we also want the horizontal alignment to be centered and i think that's it for stackpad so we'll leave it on one line and we're gonna say i want a text box we'll give it a name of message and the um let's put let's call it message input and the min width is going to be 300. the reason i said um message input is because we also have the value coming from this back from the server when we the event the name we give that string is message so we have a string called message and also a text box called message could be confusing that's what i call it message input okay let's say the margin is going to be 20 on this like so and there's our text box and then we have a button and in fact let's um let's copy this button nope let's not yes let's do it i'm going to copy it i'm not a huge fan of copy paste but um in this case it just saves us some time this is a send message button we don't need a grid.row because we are or the horizontal center because of the fact that we're not in the grid anymore we're in the stack panel which is in the grid we do need the um the same padding and margin on this button and this is not going to open connection it's going to be send message so you open the connection you type your message in we send message you may say well tim wait a minute uh what's the user we're just gonna hard code the user just say it's hey it's from wpf client all right next up we're going to have our display of the messages and for this i'm going to use a scroll viewer if you don't know a scroll viewer allows you to have a scroll bar on something if you don't have that it won't scroll but you might have things off the bottom of the form so scroll viewer where i say grid dot row is 2 and then the margin is 20 like everything else and the max height let's put it 200 and the vertical scroll bar of visibility is set to auto which means it won't show if it's not needed inside the scroll scroll viewer is the stuff we want to potentially scroll and that's going to be the list box so list box inside here we're going to give it a name equals messages and the horizontal alignment we want to be stretched to it take the entire scroll viewer and let's go to the next line here and we're going to say padding is going to be again 2010 the space in between and border thickness equals zero i want border on it and self-close that so there's our list box with all of our our stuff in it for our uh our messages so that's really all the code we need i'm sorry that's all the xaml we need to get this set up now let's go to our code behind which gotta love all these usings we don't need let's add the using we do need so using microsoft.asp.cor signal and we'll also have a using for system any using for system dot threading dot tasks i believe and system not windows yep i think those are the ones we need let's just because we're being tidy here i move it down but also just so you know you can do the quick action refactoring and convert to the file scope namespace kind of a nice little addition there so now that we have this set up we're going to open up a hub connection so we have first of all our hub connection we'll call it connection this is our connection to our blazer server hub after that inside of the constructor the main window constructor we're going to say connection equals new hub builder connection should look familiar so we did this already once and we'll say dot with url and we give a url we're going to skip that for now um actually you know what okay i know it localhost colon 7181 i believe is what i saw and then it's chat hub that's the full path to our our server and then with automatic reconnect and then finally the build now how do i know what this is for sure if we go to our blazer server and we go to properties and expand it we see launch settings.json open that up and you'll see here for the blazer server which is our kestrel environment which is what we use by default when we hit play notice it says blazer server that's this name right here so with that profile we have two versions of our site we have the http version and the https version but in program.cs down here we have the use https redirect which means that if we launch the http version it's going to redirect to the https version so instead of this it is this which is the https version which is localhost 7181 and yes it's https so https localhost 71.81 so i did remember so that's that same connection that we did inside of the uh the blazer server project in the index page so on the index page right down here we have the same connection but this time we're just on a client we're not on the server too so we're just connecting to our client and so we say there's the url all right so now we have our connection but i want to show you a few extra things you can do inside here to make life a little better for you so first one is we're looking at three different events so connection dot the cool thing here is if you click down this little lightning bolt show only events notice there's three events here we have reconnected reconnecting and closed so let's start with the reconnecting this is if you aren't connected right now but you're trying to reconnect that's the with automatic reconnect that's what's gonna when that's happening you can know that because this event will fire so we're gonna add plus equal we're gonna add a new uh handler to this event where i say sender not comma args just sender and then we have the arrow function and then curly braces where i say this this did this dot dispatcher dot invoke and then arrow and then inside here we're going to say var new message equals attempting to reconnect and then i say messages dot items dot add new message has semicolon at the end and down here the bottom and our semicolon but we're not quite done yet because it says here uh not all code paths return of value was expecting to have a task be returned but we're not doing anything asynchronous here we could um the invoke asynchronously or we can say actually let's just um invoke async and this return nope let's just here instead of invoking async which we can do we can also just say uh return task dot completed task what this does it says hey we're gonna wait on this once we weigh on this then go ahead and complete this task and return that completed task so this is just a a constant essentially that returns a successfully completed task and that hand that satisfies our reconnecting so what's what's happening here well we're going to add this message to our list of messages where's list of messages well if you go back over here we see a list box called messages so we're adding it to our list box so it's not just chat messages we'll see that that message box will also see attempting to reconnect if we lose a connection now why did i wrap this inside of this.dispatcher.invoke well because this is an event it can be fired on different thread so therefore we don't know if we have access for the same thread as the user interface well we are talking to user interface stuff so i'm going to invoke this in order to make sure it invokes on the calling thread on the ui thread because that's the caller the origin original caller therefore we should have this add to the list so with that being done that's the reconnecting event now let's do it two more times essentially let's copy the whole thing and paste it again this time instead of reconnecting we're going to have reconnected meaning we have just connected to our server so let's say instead of attempting to reconnect i'm going to say reconnected to the server i'm also going to clear the items so messages messages.items.clear will clear out previous messages so if we reconnect to the server i am going to clear out all the old messages and then put this message as the only message and it says reconnected to the server that's a clean up thing you could or could not do it's up to you and then we're going to do this one more time let's paste this back in where i call and this can be closed event so we're going to do all three events here and this one's going to say uh connection closed just tell us hey we're done and we're going to add that message but we're also going to do two more things the open connection dot is enabled it's going to be true and the send message dot is enabled is a false so we have two buttons on our form we have the open connection and send message we're gonna make sure this one open connection is enabled because if our connection's closed we want the ability to re-open that connection but because our connection's closed we can't send messages so let's disable the send message button now this may give you a hint that we're going to swap that down later when we open the connection we're going to not allow the connection to be reopened because it's already open and we're going to allow us to send messages because we are um we are connected so in fact we should set the is enabled on our send messages to false so by default we can't send messages okay now we have that done let's create some events so let's create the open connection event first i can double click on this button and it will create a new uh private void open connection on a short click and names it based off a button and notice over here my xaml it adds this click event with this right here i could have manually put click equals and put a name and then it could have created the had it create this method for me but double clicking is easy so with this we're going to say connection on string string i can spell and this is the receive receive message comma user message and there i have our arrow and in here this is the same thing as what we did in our index page let's come down here right here same thing so in here let's press semicolon the end to be complete come back and we're going to say this actually we can just copy let's copy this one right here this dispatcher.invoke same thing dispatcher.invoke and we're gonna say instead of this new message being this we're going to say dollar sign let's use the same format we use on index.razer so this just message colon user that's it we're going to add that to our our messages items so that will add that new message any time we get the receive message trigger so whenever this does clients all send async receive message this will trigger and we'll put this message this user colon message onto our list of messages and notice we're not wiping out that list of messages because we want to see one then the next and the next we wouldn't want to have it wipe out things over and over now we're not done yet on the the connection click okay so we've we've set up our connection with this event but now we have to actually start the connection but remember i said that we can wrap this in a try catch and we'll catch the exception ex and we're not going to throw it again but if we have a exception we're going to say messages dot items not dot clear items dot add ex dot message and that's gonna put the exception message onto our list of messages notice we don't have to wrap this in a this dot dispatcher.invoke because we're on the ui thread but in the try we're going to say await connection dot start async so that starts the connection and let's go ahead and say messages dot items not not clear um intel code is nice but it doesn't always know what i want to do add we're going to say connection started like so sort of add that that to our our list of messages and then we're going to say open connection dot is enabled equals false so the connection is already open so uh make sure that button is disabled so you can't try to open it again but then we're gonna say send message which is the other button is enabled equals true so that button will be enabled so the open connection button will be disabled the send message button will be enabled as long as we successfully start the connection to the hub and we don't have any exceptions so this just protects us in case we try to open a connection it doesn't work and then we wonder why everything's broken well this would in fact throw the catch and then we had that message in our list saying hey here's the reason why we couldn't connect to the server maybe it's not there all right so that's all we need to do for the open connection click let's go back up here and we need to have the send message do something let's double click that and a send message we're wrapping a try catch as well and again we're going to catch the exception and we're going to do the same thing we're going to grab the messages.items.add.exe.message paste it in there and in here we're going to say await and we're going to say connection dot invoke async and we're going to say the send message this is this is the one broadcasting out our message so we're gonna say a send message and we're gonna say it's from a wpf let's do this new new line it's from the wpf client remember i said we're gonna hard code the user well here's how we're going to do it and then we're going to say message dot not messages message dot text oops message input message input.txt so i grab the the text box or us send that message to our our hub all right that's all we need to do we're all set up so that if we hit save and if we hit run it's just going to run the server let's go back up to our solution right click on it and we're going to say set startup projects instead of a single project we're gonna set up multiple projects and we're gonna set the blazer server and the wpf client hit okay so now multiple projects will start at the same time um just wait let's save everything and rebuild this normally works but every once in a while visual studio yells at me um yes enable ai assistant telecode sure cool great awesome thanks all right so it's saying hey we can't launch both of these which is baloney you can oh it's not baloney it's just tim forgetting how to do things so i have multiple startup projects let's zoom in here because it's a font small multiple startup projects but the action on both of them is none so no this is not microsoft's problem sorry microsoft this is tim's problem i said i need to say start on both of them hit okay and now we're good to go so let's bring the this is the blazer server let's shrink it down a little bit and then let's also bring over our wpf connection let's first on the dpf notice we're not connected because it says open connection is enabled let's click it and it says connection started cool so if over here i say tim and i say hello world like so and hit send it says hello world on the wpf client and on the blazer server project but then at wps side i can say hello tim and hit send message it says over here and over here on both sides it says wpf client says hello tim so now we have a desktop app that is also a client of our server so the server has to be web-based because it makes no sense to be just desktop-based but the the clients could be just desktop apps now remember i said that the um the connection would retry let's go back without closing these let's go back and go to our solution and we're going to right click on the solution and say open folder in file explorer which opens it over here we're going to the wpf client and open that up bin debug dotnet or net 6.0 windows i'm going to copy all of this open up a different folder i'm going to say wpf inside here i'm going to paste everything i just copied let's move this one off the screen and now this is a copy of my wpf client i haven't published it this is a quick and dirty version but if i open this up i now have another wpf client and i can't open connection my connection started but notice i don't have the other messages that i had from the original one because this one just opened the connection it's only been listening for a few minutes but i can say this is my standalone wpf client and hit send message and notice it came over here it came over here it's also in the web server we're not going to open that up but if i move this off the screen for just a minute and i hit stop over here notice it says attempting to reconnect it's lost the connection to the hub but it's trying to reconnect now if i start this back up and i wait for a minute this will be able to reconnect to our server if i didn't wait too long there we go reconnected the server i didn't do anything i waited for it and it's done now the wpf app the other one is open and i can connect i open the connection but now if i send the same message again it gets the message so this one this was the standalone project and it reconnected when the connection was lost now if we stop this and wait 60 seconds i'll pause a video a minute but it's going to transition from attempting to reconnect to closed connection all right it just closed the connection so since it closed a connection or the connection was closed because there is no way to reconnect it it disable the send message and re-enable the open connection now i'm going to leave this like it is i'm going to start this up again and once it starts i'm going to bring back over this client and i'll bring over my my web servers to show that's actually doing it and i'm going to say open connection again open connection connection started send message it has connected to the server now that's available again so you can use these events to for example if you're disconnected or you can't connect or you're reconnecting and waiting for that you could queue up messages and once you reconnect then you could start sending those messages from the queue and then keep you know get back to to real life so a lot of stuff you can do here that is pretty impressive now i did say that i want to show you how to do a connection where we talk to the counter so it's not just this send a chat message but we're already pretty deep in this video so i'm gonna do is do another video where we add on to this video part two where we'll we'll talk through hey let's create an on the same app we're gonna create a new uh hub that is going to instead of taking two strings it's gonna take a string and an integer and that's gonna change our counter from our wpf app or whoever calls it so we'll do that in part two until then thanks for watching if you have questions about signalr let me know down in the comments if you want to see more about signalr then leave a comment down below let me know your thoughts are on different things you want to see but also go to suggestions.iamtimcory.com and upvote a signalr suggestions there or add your own because that's how i know if these video topics are what you want and how many people are interested in it based upon how popular they are so i would definitely encourage going there but please leave a comment down below as well what your thoughts are on single r that does help the the video uh spread throughout youtube and get more people interested in signal r and get more people to understand how it works all right thanks for watching as always i am tim corey [Music] [Applause] you
Info
Channel: IAmTimCorey
Views: 70,889
Rating: undefined out of 5
Keywords: .net, C#, Visual Studio, code, programming, tutorial, training, how to, tim corey, C# course, C# training, C# tutorial, .net core, vs2022, .net 6, signalr, websockets, long polling, wpf, blazor, asp.net core, blazor tutorial, blazor server side
Id: RaXx_f3bIRU
Channel Id: undefined
Length: 72min 1sec (4321 seconds)
Published: Mon Apr 25 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.