.NET 6 Blazor 🔥 Chat with SignalR using WebSockets

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello my dear friends i am patrick god yes this is really my last name and you asked me a lot actually about signal r so how do you implement signalr with dot net 6 meaning we're using web sockets and we build a sample chat application i used the code a little of the code of the official documentation of microsoft there is an example so if you just want to read the text and use the code there then stop the video go to the documentation of microsoft please and then build your own chat but maybe it makes sense and you will be rewarded if you stick with me here because we will make this chat a little bit better we will as you can see right maybe here or here i don't know you can see that we will add the usernames you can see who joined the party who left the party who said something and so on and we will also use a text area instead of an unordered list and then add list items to the chat messages this is not what you really want with the chat i want an old-school irc chat if you are as old as me then maybe you know what i'm talking about and if not then well then not anyways signalr blazerwebassembly.net 6 this is what we're going to do now and if you learn something i would really appreciate it if you click the like button and subscribe to my channel don't forget to hit the bell icon thank you so much for that additionally maybe you want to have a look at my newsletter i promise i won't spam you i just send an email once a week at most and with that you get videos like this one here earlier in your inbox you get more information and also early access to upcoming online courses and sometimes yeah discounts of course but the uh course that is coming soon let's say is a really really big one where i want to focus on getting a job in the dotnet 6 and laser world so everything regarding these technologies and also interview questions scrum may be a bit devops so stuff like that and if you want to be the first to know what is going on there with this course and maybe see that course long before others can check out the newsletter please and last not least as always guys thank you so so much for the coffee as you will see in the tutorial i was a bit confused so maybe i just need more coffee and then these tutorials will be a bit better all right long story short enjoy the tutorial all right here we are visual studio 2022 we create a new project and we want to create a blazer web assembly application of course since we want to build a chat with signalr and blazer web assembly maybe you've got it in your recent project templates or just choose it here in the list of templates or of course you can search for it i think you know this already we call this thing blazer chat signal r maybe and then this is important now we select asp.net core hosted because with that we get a server project as well where we will put our signal our logic and i can already tell you that this thing is then called a signal r hub this is not a service or controller maybe you know this already from a web api implementation check out my tutorials maybe here we are going to build a hub but before we start with that real quick we add the signal our nuget package to our client so right click the blazer chat signal our client project please and then manage you get packages make sure to select the browse tab and now let's just enter signal r maybe and then we should find where is it microsoft asp.net core signal r but i'm actually looking for signalr and then client so let's also enter the client term here that's the one microsoft asp.net core signal our client that's the one we want to install for our blazer web assembly client click ok i accept and this should be it okay and now to the server project typical way to do this is we right click and add a new folder and this thing now is called hubs because we want to create a signalr hub here again if you are used to implement web apis using controllers for instance or then services as a better practice and then inject these services in the controllers by the way there is a construction site next to my apartment i hope you do not hear this otherwise i'm really sorry about that apologies for that now we won't inject any services like you can see here in the other tutorials we have a controller then inject the service for that we would then create a services folder but now it's a signal our hub so a hubs folder quite simple i guess and in here now we create a new file so add a new class and we call this a thing already chat hub that's it all right and now that's important this one inherits from hub and we use control and period to see the quick fix menu now and we want to add the reference to microsoft spin core signal r that's it already now we've got our signal our hub and now the important thing here is we want to be able to send messages to all the users all the clients that are connected to that hub and to be able to do that we just write a method called send message for instance so public async task we call this method send message and now you can in essence add whatever you want to add for instance if you just want to send a message so any string for our chat in particular we just enter message but maybe we can also add a username so string user is something we want to add as well now this is parts of that are from the official microsoft documentation so don't get me wrong not everything you see here is invented by me of course but i will change the chat a little bit made it a bit better i think um so maybe you still want to stick with me here okay and now in here we have an object called clients now this is from sig null r from the hub right so and here we can say to all the clients we wanna send something send async intellicode already knows what i wanna do and we send the user and the message as well as another string and this string then is used to identify this message on the client so the typical way is something like receive message and then on the client you will see this in a minute we listen to a hub event that is called receive message so this is no convention nothing like that we could totally enter something else like get that message dude why not i like that so let's stick with that and this is everything we need so far all right so if you just want to send messages you do not want to react to a connection so when a user connects to the hub or disconnects anything like that this is everything you need crazy right still we can already add something else so as i just said on a connection when a user connects there is a method we can override so public overrides almost overwrites asynctask and then on our i think there was it already on connected async so when a user connects to our hub here we can of course call base on connected async and also wait send message and then something like no user here but uh user connected all right and with that then every client that is connected to our chat will see when another user connected now what i wanted to change here is i also wanted to send the username for instance to the client but we do not really have a username with all these client objects we have a connection id and people use this connection id then to also store a username but this is something for later the next thing i now have to add is we have to register the signal our service and we can also add a response compression this is not necessary but as mentioned in the documentations they do this so why not do this too so we go to the program cs and now here with builder services not configuration services we just add add signal r that's it already and now regarding the compression we write builder services and then add response compression and this thing gets some options so options and in here now we say options mime types response compression defaults and then mime types concat new and here we enter the string [Music] not in parentheses in curly braces actually application and then octet stream i think that's it let's see here's the dot missing okay maybe we can format this a little bit so we've got and i just removed this nice what happened here options mime types response defaults okay now here i think now that's correct okay and after that we also add the middleware so app use and then response compression okay so again this stuff not really necessary but recommended in the docs so why not use it as well but what you really have to do is we have to add the end point to our chat and we do this down here so this is really important app and then map hop and then our type that would be the chat hub and this is in our hubs namespace and in here now we give this thing a route for instance forward slash and then chat hub okay so this thing is really important because with that then we are able to connect to our chat hub from the client and with that the server side is done for now as i already mentioned i want to improve this later meaning i want to see the actual name of the user that joined the chat and i also want to see when a user leaves the chat so on disconnect we want to display a message but again this is done later now the next step is to actually save this and then we go to the client all right and on the client now we add a razer com read razer component code in essence we do not really add a new component we could do that of course just call it then chat for instance and make this a shared component and then use it in the pages folder here in some page for instance or what we can do is we just modify this page here already so in the index page let's first write some code so we remove this all right and then we add the code block here and now we need some stuff first is the hub connection so private hub connection this can be null we call the sub connection all right then next we add our messages what uh what do i mean by that so we have a string let's also use it as a private string call this messages first this is an empty string and what i want to do with that is i want to display a text area again this is different to the the example of the microsoft documentation there they just add new list items to an unordered list but this doesn't really look like a real chat and what i wanted to do was use a text area here and now this text area well the value of the text area is a string these are the messages and this is where we store these messages in essence so this will be a really big string in the end maybe when you have a long chat session with someone so this is where we store our messages and the next things i think this is clear we've got a username which is an empty string at first and then we have the current message the user entered in an in a text field for instance okay now the more interesting stuff we want to connect to our signalr hub so we write another method private async task call this connect all right and now in here we say regarding the hub connection this is a new hub connection builder and now in here we say with url because we need the complete url to our chat hub and we can use the navigation manager of blazer for that so let's inject this one real quick at inject navigation manager navigation manager and now visual studio recognized that it doesn't know what this thing is so we add the using force microsoft sbnet core signal our client or what you can also do of course is we add it here to our imports eraser file there we are and now the index also knows what this stuff is and now regarding the navigation manager here we say to absolute uri and in here now we enter our endpoint chat up right this thing we entered here in the program cs of our server project map chat hub is the url and here you see this again and now we say build and this should be it then with that we get our hub connection and with that we connect to the hubs well this is not totally right we also have to call a start async method but with that we will then call in essence or this method here is then called the unconnected async so just keep that in mind regarding this hub connection now before we actually start it right we can say await hub connection start async this is what i was what i forgot a second ago so with that we connect but we also want to listen to the messages that are sent right so we have to add this listener here and we do that with hub connection on and then this is what we expect to strings and then we want to listen to the the name of that message remember the default way is to call this receive message but you can enter whatever you want so for instance we just enter get that message dude and then in here we add a little a method with lambda expression so user and message are the strings we expect and with that we also add some logic here and we say that our actual message then we encode it a bit we say this thing now looks like that this is actually a little function [Music] if the username is null or empty then we add this thing here and otherwise what i want to do is i want to display the user and then a colon and then we add the actual message okay i hope this makes sense so if we see a user or we get the username and a message then we display user colon and then the message and if the username is now or empty and this happens actually when user connects then we only want to display the mess and the message which is then user connected right otherwise we would see an empty space and the colon and then the message and this is well this does not look pretty nice okay so with that we've got our let's say encoded message and then we add this to all our messages for the text area and also add a new line with that and now the last thing that is important since we are using blazer here we have to tell our component that something has changed so please re-render and with that we have to call state has changed and now let's also add a little bit more so first thing i want to add is a send message send method then a flag is connected so maybe check the current state if the user is connected and then also on dispose we want to dispose the hub connection so again parts of that are from the microsoft documentation so please if you want to know more have a look there or just ask a question in the comments section thank you for that so the send message method jesus message method it's hard async tasks need more coffee i guess send and then here we say if our hub connection is not null okay then we say await up connection and the formatting works amazingly today oh come on up connection send async all right and then we want and this is again important what we want to do is we wanna called a specific mess method and the method we want to call is called send message jesus christ okay so we do not actually call the send message method here in the client as you can see it's not called send message right it is called send async and with that we send information let's say data to our signalr hub and this data should consist of the actual method then we want to call and this thing is then sent message now to make this more clear maybe we can call this i don't know send add a add message to chat okay so maybe this is a little bit better then and now with that regarding the uh the the messages and the username we just add this stuff here and then i want to reset the message so the user doesn't have to do this manually so this is our send method jesus this was complicated and now the flag public bool is connected is hub connection almost i want the field actually so up connection state come on state equals hub connection state connected okay and now the last thing public async value task again i don't really think this is necessary here for this little tutorial but let's do that anyways if our hub connection is not now then we say first let's get a bit more room here a weight up connection dispose async okay so far what's going on here connection app connection oh sure yeah okay now this works great okay and with that i think the first part of this code here is done of the code block and now let's switch to the html so we've got the page route here this is just a forward slash this is our index page we've already injected the navigation manager and that the amazing or the dispose stuff makes sense we also have to implement an interface here i async disposable all right so this is everything regarding the injection here the using directive we move there to the imports razer keep that in mind and now first maybe the title this is our sick now our chat also we can give this thing a little header here or a little title signalr chats okay and now what i want to do is i want to display an input field where a user can enter the user name and a button to connect to the chat this should only be displayed if the user is not connected i think now the the flag the is connected flag makes more sense right and otherwise if the user is connected then we display the text area an input field for the actual message and also a button to send this message and don't worry we will also implement using enter to send a message so i think this makes more sense then so if again the user or the client is not connected then we add a div with the class which is input group this is from a bootstrap five if you're wondering so with this blazer represent the template here in visual studio we also got bootstrap five so and now add our input and we bind this to our username and also let's add a class here class should be form control so it looks a bit prettier and yeah maybe a placeholder what's your name all right okay then a button also with the class close this already which is button again bootstrap 5 here button primary and also to make this even more prettier form control append right and if the user now clicks here so on click we call our connect method and we also add the text connects okay and this is now our screen if the client is not connected and now here first the text area for all our messages add a little inline css i know we should not do that but i don't care so inline style width is 100 and let's set the height to 500 pixels with a 100 percent not just 100 pixels 100 percent and what we'll do also in a minute is we will use an element reference here in the end i can already tell you that we will do this because we will see when we test this chat app that the more messages we get a scroll bar will appear in this text area but this text area won't scroll to the bottom but of course we will fix that here in this tutorial so please be patient and stay with me because we will do this in the end this is the last thing we will do but not now now we just add our messages here and we're done with text area okay and now another div for another input so class input group that's correct and now input bind value this time because we want to use enter here to send a message i told you that right you paid attention of course so what we have to do here is for the event we say on input okay and with that event then we also can listen to on key up and call another method we will write in a minute handle input otherwise i think the default event is on change right when we would just use bind like we did up here then the event is on change but we want to change that a little bit so on input we want to bind the change of this um this value and also on key up then we want to call another method here and we add again the form control class here and this should be our input then and the last thing that's missing is our button [Music] so class button button primary form group appends all right let's close this maybe and on click we call our send methods and we can also well we can disable this thing if the user is not connected so this should look like that all right this should be the html part and now the last thing we have to add is you see it here the handle input method so let's edit here maybe yeah private async task handle input and now here we can uh read the keyboard events so we keyboard event arguments call this arcs and if now the key is null or the key equals enter then we call send but i think this is not really necessary i think this is some copy paste stuff i got for my courses yeah we don't need that okay so the key is enter and then we send otherwise we use the button then we send the message and i think we can already test that so let's save everything and start the app and then let's see usually we have at least one error now but let's see so it's building build succeeded and i hope in a couple of not hours please we should see the chats yes there it is on my other screen and you really get an error jesus christ okay what's happening here um fail to execute set attribute on element class button is not a valid attribute name okay why didn't you tell me i think i should go live sometime and then i will see this in a chat when you tell me patrick jesus what are you doing you idiot come on okay and we have to restart this manually i don't know why this is happening with visual studio it worked it already worked but now with all the updates it is not working anymore okay we've got our connect screen isn't that great let me still open the console here don't know maybe something is happening and can we open the console yeah nice so what is your name [Music] okay it connects there it is user connected nice this is said we do not see something here should add this sent format this save this it's not rebuilding right is it reload nope nothing restart and let's see okay again iron man is connecting here the enter does not work of course because i was lazy so now we [Music] hi anyone okay this is a bit sad again maybe we can just open another window like this one and let's put this here and here okay so we've got iron man now let's also connect spider-man we have to use the mouse see that user connected there is another user i don't know why this did not work no it does i hope right okay and now let's say hi how are you great exclamation mark okay so this seems to work and grammarly is telling me that this does not look does not look correct okay whatever so this is nice and this already works in essence this is the whole signal our magic but now i want to make this a little bit better so if you know now everything you think that you wanted to know and you learned everything then please you can give me maybe a thumbs up maybe subscribe to my channel and then you can stop the video but if you want to see how we can also add the username to this uh status message let's say and also how to um scroll to the bottom because problem is we can hit enter a couple of times and you see there's the scroll bar and if i say you know hi again as spider-man we do not see the message this is this is not nice i think so maybe we should fix that so back to visual studio there it is and now the first thing i want to do is let's add the username to our connect and disconnect message now the option you have with a signal r here is in our code you see this this thing here to absolute uri and okay this is blazer but we see the endpoint we want to connect to right and here we can add query strings all right so what you can do is we add in a question mark and then for instance say my username now is the username i entered in the text field so this should be username then and that's it that's it for the client all right so this is how you add data or send data to the to the signalr hub now back to the server the only thing we get here i mentioned that already in the beginning of this tutorial and maybe you know this little question what is the only information well it's not the only information but the information i mentioned at the beginning of this tutorial when we create the signal our hub it's the connection id so this is everything that we can what this is this the thing we can use to identify a user and it's not the total truth because when we would use a real login system let's say with authorization and roles and stuff then we could add the authorized attribute here on top of the hub and then we would have the currently authenticated user available so for instance check out my other tutorials please regarding json web tokens and uh using that in the web api we've got a json web token for instance and in there we we we have some claims and these claims could be the role the username the user id and so on and then from there we could use or take the username but still this is not signal r right so this is then again other authentication stuff where we will where we then could see okay this message was just sent by the certain user but if you just want to use signalr so if we just say this is an old-school chat like in the old irc times maybe good times really where you just enter a username without any credentials and then say okay i want to join this this chat channel here then you have no other information and no other option to do it like that we have the connection id and we want to store this connection id with the username but what we can do here and i think this is the easiest option for the current session of this chat we just add a dictionary right so private static dictionary and if you think this is total bs please tell me that in the comments as well i'm sure it is because there are i'm sure there are better ways to do this but i think for this quick and dirty youtube tutorial it's the easiest and quickest way so we've got a dictionary with two strings right so this is a hash map in essence and now whenever user connects we just add the connection id with the given username to this dictionary and then when we get the disconnect event we look the connection id up in this dictionary and then we know the username and the user that currently disconnected from the channel so on connect we have to add something to get the username now we say context get http context we got a request here then and here we say query and then username that's correct intellicode you are so intelligent and now users add and then not username first i want context and then connection you see there it is this is the thing i talked so much about and now the username and now in here actually let's use string empty here it's a bit better and here know we can say and i love this just say user name not connected it's boring joined the party okay now what is wrong here the parenthesis all right so now with that we can already see the username but more interesting now really on disconnect we want to also display the username so public override asynctask undisconnected async that's correct we need an exception here okay and now in here we say oh my username let's get some space again is users and then first or default use user u for user and then the key is context connection id and from that we want the value okay so again we look up the connection id in the keys because here this is the key this is the value in the dictionary here and from the result then we want the value and this should be then the string so the actual username and then again we send a message oh wait i renamed the method here add message to chat and this then is string empty again for the actual username and here we add our username and then say left the party something like that of course again there is room to improve that for instance instead of using a uh the same method here add message to chat we could i don't know write another message method that is called add state message at informational message something like that and this is just one message so we didn't have to uh use the string empty and then encode the message in the uh and the client and so on but i think you get the idea for now and yeah this is how we get the username i would say we test this again so restart the application open this chat and the other chat and maybe we can just reload so again we've got iron man and see that iron man joined the party and then let's add batman this time batman joined the party nice and what happens now if i add a third one just want to see this here so again spider-man connect okay we see spider-man here and now let's pay attention here i just closed the tab spider-man left isn't that nice this is great i love this this is really amazing and there are so many possibilities now with signalr and it's so easy how much time 40 minutes maybe 40 minutes and we've already got this built this works this is amazing and you cannot only use that for chat you can build your own game here you can use it in an e-commerce application or a social network regarding notifications for instance lots of stuff uh that that you can use this with or use this for what's the correct english i don't know anyways now the last thing i told you already now again when we enter or send lots and lots of messages here we see the scroll but now we want to scroll to the bottom of the text area so this uh we do next here and then we are done with this tutorial sorry if this was a little bit confusing i was i was a bit distracted by the construction side here but still next thing the scroll to bottom so in the text area first we go to the client here's the index raiser and now what we want to use is an element reference right so we can do the following we say where is the text or here it is we add something like this and ref text area ref and this is now an object we need in our code as well of type element reference so element reference and we call this text area ref and with that now we can access the text area in our code block and to do that we well we could do that now already but regarding scrolling to the bottom this is something and it's it's really sad that i have to tell you this but this is something blazer cannot do by its own so we have to write javascript code i know i know so how do we do this we i need the javascript interop in a sense or the js runtime but first let's write the method really quick so we add the method in our where is it in the index.html so in here see that we write our tiny little scroll to bottom method so in here in the header we add another script block script type is text javascript and now the function is called scroll to bottom maybe and this is how you do um well how you can add your individual javascript code anytime of course you can also add a javascript file and reference it here in the index html and then you can use all the javascript you want but let's keep this short and simple here we need the text area and with that text area now we say text text area text area this one scroll top so the position the scroll position of the text area is the text area scroll height compile errors yeah that's okay just stop the app so text area scroll top is text error scroll hide looks a bit hacky and well that's javascript what can i say so with that then we go back real quick to the index phew blazer again nice and in here now we inject the js to runtime so inject i j s runtime call this j as runtime and now in our connect methods method here whenever we get a new message we scroll to the bottom so jsruntime and then in here we say invoke ace no avoid async it is avoid async do not use a weight here but there's only the invoke void async method and we call the method that is called scroll to bottom double check scroll to bottom better copy and paste this and then we give this thing what it wants and in this case this is our text area so this is the element reference again at the semicolon here and you see here we just added this object this is the argument the parameter this method needs all right let's test this again okay please excuse the edit sometimes i just jumped here because it's a bit hard to i don't know why because i have a couple of screens and sometimes it's hard to place the windows to the left and the right but anyways again iron man wants to join so connect there it is he is now let's say wonder woman wants to join as well hey there what up okay i could do this the whole day but now let's see iron man says what up we see the scrubber one woman says nothing see that grab some coffee sure nice we scroll to the bottom we can close this and one woman has left okay and here is this little blank we could also fix but i think you get the idea see that let's restart the app iron man and now this is fixed as well okay awesome the chat works now let's push this to github real quick laserjet signalr this is not private this is public for you guys and you can now check out the video description for the code and then you've got your own signal our chat and blazer web assembly so that's it i hope it was not too confusing in the beginning or maybe also in the end and you did not hear the the construction site sounds i hope you learned a lot if so please like button and subscribing that would be really really nice don't forget the bell icon thank you so much for that again check out the newsletter please if you want to get all the information regarding dotnet 6 and blazer that would well maybe make you a developer then this might be something for you but additionally of course there's also other stuff like the videos here you get them earlier in your inbox then and sometimes i also post some articles so maybe this is something for you as well and last not least thank you so so much for all the coffee guys because with that well what can i say i can turn the coffee into code and i am able to well get the time and stay awake when we already put our little boy to sleep yeah that's that so thanks again very much for watching for your time and i hope i see you next time take care you
Info
Channel: Patrick God
Views: 33,767
Rating: undefined out of 5
Keywords:
Id: OBsPTuvW3ok
Channel Id: undefined
Length: 48min 1sec (2881 seconds)
Published: Tue Feb 15 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.