Asp.Net Core WebSockets Vs SignalR. Which should you use? (Full Course)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] so real-time web applications are fairly ubiquitous now think about things like gobo where you see the cars moving around on the map and real-time and even things like facebook messenger for your chatting and talking back and forth with your friends in real time but how do you build a real-time web application and more specifically how do you build a real-time web application in dotnet core using WebSockets well my friend stick around and you'll find out [Music] well hello wherever you are when ever you are wait am i couples have to think about that I'm in Melbourne Australia I can't believe I forgot that ok and when is it it's july 2019 so it's been a while since I've made one of these videos one of these tutorial videos so I'm so happy I'm so glad to be back doing it because I absolutely love doing it and I'm really glad that you could join me for it and I'm hoping that whatever you are whenever you are that you are happy and healthy it will and it's great to have you with me so as I said in the first introduction this is a video about real-time web applications specifically using WebSockets and even more specifically through the lens of dot air core and c-sharp now in this video we're going to be doing a full truthful step-by-step builds we're going to build a client chat application but we can send messages in real time between multiple flying endpoints with a salvo sitting in the middle we're going to do two builds we're going to do the first build there's going to be a WebSocket build dotnet core WebSocket server with JavaScript clients and our second build is going to be a dotnet core server using signal are and we're going to have JavaScript clients using the signal our library and look Mont of why you may want to do that a bit later in the video so next we're going to actually look at those apps that you're going to build just so you can get a flavor of what you're going to end up with and how things are going to work before we do that just one last mention if you haven't already subscribed to the channel please do so thing the little bill and that way you'll get updates when I post new videos if you don't want to do that that's okay I'm glad you stopped by and watching the video enemy but it would be nice to get another few subscribers it just makes me feel so much better about life anyway with that being said it makes no take a look at the applications you're going to build ok so what we're looking at on screen here is our WebSocket chat applique and I've got three separate instances of the client app running just so we can see messages going between the two of them and then our background they are in the background we have the WebSocket cell bar messaging server just sitting there waiting to receive and send messages oh so let's connect four clients on will connect all three you can see they get back this connection ID from our server that's something we have to build because WebSockets don't come with any king of management wheels so we're gonna have to build that's part of our build and we're gonna have to build our routing engine as well so let's have a look at that now so we're gonna have two very simple routing rules the first one is just a broadcasts or if we just type in a message hello and we click send then we get a broadcast message out to all of the connected clients you will see that in addition the sending client will have this entry in its communication log now that's because we don't have any recipient IDs placed into the recipient box now this is a bit clunky I was thinking about generating a drop-down I decided to leave it out because it would just make the tutorial too long so instead we're gonna have to manually cut the client ID from the client we want to send to paste it in here so we're gonna send the message from this client to that client only to go along again and this time we'll see a message outbound here you won't get an inbound message on a client too and we should only really see nm boned server to client message on this client yeah so we click send and deep that's what we get and poor old client one was left out of that messaging so may seem quite simple but there's a lot going on there we're gonna have to cover an awful lot to get that up and running it actually surprised me even though the web socket API itself as simple and it is to get this up and running on dotnet core I actually found it quite challenging there's a lot what to do if you want to do it right so we're going to do that but before we move on to our build let's take a look at the signal art application okay so we're now in our signal our version of exactly the same application chat application this time we're using signal our prizes to those of you who can really see any discernible difference other than the word signal are appearing on-screen the only one that really you will notice if you're very keen eyed as the sailboat connection URL is slightly different and all will become clear otherwise everything works and pretty much exactly the same way reconnect then we get back an ID and then we can send broadcast messages or we can send powered targeted messages to other clients I'll just show you that just to show you this it's all working oh you didn't copy even copy the full string that's fine let's just do that just to show you okay there we go so the reason I made the client sort of the applications generally saw similar is so that you can actually compare and contrast both the build process and how they how they fit together very very well you can compare them very closely because of doing basically the same exactly the same thing and you may then choose to take one approach over the other now I'm not going to preempt that I have my own personal viewers on it that will be revealed later so having had a look at the apps you're going to build before we actually jump into building them let's do a little bit of theory there's not that much just to level set the playing field and get as all starting from the same point before we launch into the build process so let's go and do that now okay so yes this is a step by step into WebSockets versus signal art and dotnet core and again as usual we will do full step-by-step examples in both those technologies WebSockets and signal are so if you're not here for that you're in the wrong place but stick around you something may even enjoy it who knows so what you learn when done you'll understand about synchronous versus asynchronous principles just generally and also specifically with regards c-sharp programming because it's a theme that records a lot throughout the tutorial and it's something you have to understand so we'll cover that which may be a surprise we'll go over HTTP XML HTTP request and WebSockets just as a bit of background - - for web sockets are and why they exist we'll take of any brief look at the web socket API it's pretty simple and then the main main part of the tutorial is will do a full WebSockets silver and botnet core and also we'll have a JavaScript client and then we'll also couple what is signal arm and we'll build a full server application in signal art with a lot of JavaScript client as well so what you'll need text there that I'll use vs cord I recommend you use it's really good and it's free dot neck or SDK again free web browser if you don't have a web browser you're going to be really stuck and I've put about 60 minutes of your time you might need a bit more than that and it would be advantageous to have some JavaScript programming you don't need it but it would be if you know JavaScript you might just it might just floor that easier for you but we do cover everything that you need to know English tutorial so don't worry if you've never done JavaScript okay so just that just a brief bit of theory about HTTP XML HTTP requests and WebSockets know that one in the middle XML HTTP requests I might start referring to either as xhr which is correct or even Ajax so if you've done any JavaScript programming and you've done and you know what Ajax is XML HTTP requests there's part of the Jack's so it's not technically correct to say that it that is of itself Ajax it's not but it's almost sort of synonymous so firstly HTTP it's been around a long time since the 80s I believe it's based on a request response cycle so if you looked at the news on rest api's it's the videos are the examples I've done anyway have been based around HTTP in the game and the post valves of HTTP so we're still very much alive and well it's not a legacy protocol by any means and it's the foundation really of the Internet it's synchronous so starting up concepts or discussion on synchronous versus asynchronous when we say it's synchronous we mean it's just you request something you get result back you request something you get result back so you basically wait for the work to finish before you get your result back it's almost like a serial approach okay it's stateless so again this is one of the puzzles orbit you can have it scales really well you can have thousands millions of connections to a server literally and it makes a request gets resolved back and then as far as the server is concerned massive interaction done it doesn't mean maintain any type of connection or state here's a quick diagram on HTTP so as we said we make a request and the server does all the work that it needs to do and it responds back and then the Delta in between the request and response is kind of the wait time if you like and the early days of the internet that would most usually manifest itself as you've got page you submit form and another page loads as a result single page applications for stuff happen just with them in the one page or quite real and in fact they didn't really exist and so you made up we're on one page you went to the next page and the Delta and between that page the second page loading that's commit your wait time which is by a number of factors that you generally don't have control of the end point cell or than there what connection all that kind of stuff which is relevant when we come on to talk about asynchronous method messaging and method calls and then the request response cycle just begins again and there's law I've got to request response cycles on the screen there there is no linkage between the first set of request response and the second request response they are and totally independent and that's why it scales really well xml httprequest as i put there underpins ajax foster debuted an Internet Explorer 5 or thought to that in because it's quite interesting I don't know why just interests me and it allowed for partial UI updates so still request response but allowed you to do things like look up an address on a web page and there would be some activity in the backend a synchronous activity that would pull back of us also so basically allowed you to do single page applications and partial UI updates and then I just made the way that much more usable platform can be asynchronous so you can again let me I've got an example here here's a picture from the Australia Post website and I'll show you're all familiar with something very similar you start typing something in and you get our a result set that Google does it as well when you start searching and I'm fairly sure there's some kind of is synced in this process going on there and sort of means that the result sets gets whittled down you're typing into the text box is not delayed so you don't type in one character wait for a request response cycle and then you're able to a tape another character I have used applications that have behavior that I'm sure you have as well but the whole is synchronous in nature of Ajax means that you're not constrained you got to wait for the result to come back and you can keep typing and the result sets gets its what although to something more appropriate and I've also put in their XML HTTP request can be used in something called long pooling no long pooling is almost an account what's not almost as an alternative to WebSockets but with long pooling you'll make a request and as the name suggests you will wait a long time as long as you need as long as the server needs to return a bit of data back and it gives the impression of kind of real time updating and it's less chatty than short Pawlik shot pooling is basically just have you got a result have you got a result have you got a result even if there was no result available so long pooling only the tones of when that is one and that can take a long time and I believe Facebook actually use long polling in their chat application which is quite interesting so we're not going to really delve into that technically today but I just wanted to give you the background to bought xml httprequest is and why it exists and what kind of features and functionality it gives us finally we move on to the main event WebSockets saw actually a WebSocket connection start with a HTTP request to upgrade the connection to a WebSocket connection it's bi-directional which is not any massive supplies and it's but the meanwhile one of the main points of difference with other things is it's persistent or kneeled up you actually have an established connection between the client and the server that stays there the second open connection and either the client or the server can send messages in a bi-directional fashion at any time it's not waiting for somebody to do the request and then head back a response clients can just send data in both directions at any point in time it's really the closest thing you're going to get to an actual network poor board connection and it blows up and here here's a quick schematic here so the client will make a bull make a request it's a HTTP request to upgrade if we are able to sustain a WebSocket connection because not every environment can then if we are able to then we get response handshake that going yeah that's all cool let's have a WebSocket session and then you just have this one full duplex fully persistent connection with a client and silver can send things back and forth and saw ideal for real-time applications just a bit about the web socket API there's only really two methods send and Clause fairly self-explanatory so sending messages and close down the connection we have four events so we'll get an event when the connection is opened we can event when there was a message I won't go on an event mother's in there off of him well have just got on an event when it causes done no the WebSocket protocol is defined in RFC sick four or five five I put links down in the description below or of course on the blog as well the protocol from my perspective is defining more the Canon networking a type of stuff which I'm not terribly interested in and then you also have the web socket API definition which is defined by the w3c which is probably more what we are interested in I'll be honest with you the w3c documentation I think is absolutely dreadful it does the job it's just not very readable so of course as part this tutorial we will use Microsoft's implementation and the web socket class and we'll also use a JavaScript implementation of it as well which are the both basically circle around the main API definition but there are some slight differences especially the Microsoft space supply supplies but nothing too dramatic a bit about our application architecture for our WebSocket app we have our HTML and JavaScript client on the Left here I've made the conscious decision just to use HTML and JavaScript I'm not using anything like jQuery which is a JavaScript library I'm not using anything like bootstrap to provide nice UI elements the web app looks at something at the 1990s which I personally quite liked and it just keeps things really focused and really simple and what we are interested in which is of course as WebSockets then on the.net core side we have our server application we're going to be writing 3 class custom classes from memory which are surely our ingredients or WebSocket server middleware class which is going to contain this stuff that we need to establish connections and even do some routing we'll need to write our and manage our class I'll come on to PI we need that in a bit I want the one to ruin it now and there's another class that's not that's important clearly very important but I've not put it on there and we'll cover that when we come to doing the build and of course program and startup classes we'll be doing a bit of work in the startup class and a central element of this tutorial will be 11 - dotnet call request pipeline we focus quite heavily and on that because it's really important other than that relatively simple architecture now just before we go on to the build we've got two builds just to remind you a WebSocket build and a signal are build at the end and cigar insofar as our WebSocket build is concerned I've broken it down into five phases so it's not all one big bump of information so I'll take you through those first and then we'll come on to doing a first phase build of our web socket line so the build phases are get connected swing that we set up the both projects are a server project and a client project and we actually write enough cord to establish a WebSocket connection so straight off the bat you're gonna learn how to do that well then in build fees to we're going to actually send and receive messages so phase one we're just connecting sent two we're going to send and receive messages so we could potentially even leave it there but I will not leave it there for various good reasons part 3 we're going to upgrade the middle of your so this is really under discussion on the architect that internal architecture of the application and making it adhere to some decent standards in section 4 we're going to add or manage your class and that is needed and I will ruin the supplies but it's necessary to add and management layer WebSockets as you've seen over very simple it doesn't really provide that much other than this connection and so I'm adding a manager class is required to manage your connections from within our application and then finally we're going to add a rotor so it's a bit my grandiose term for what we're actually going to do but again you will see we will have effectively at this point point number four build fees for we're just going to have you could potentially have multiple clients connecting in but they're all effectively independent connections one client cannot send a message to another client so we need to add this routing functionality on ourselves or so we can start rotating messages between clients which is really the entire point of a chat application which is what we're building so step 5 it's absolutely necessary so with that that's our introduction and what you're going to learn done I think we know move on to build phase one or a WebSocket application all right so we're going to get started on build phase one which would all get connected and in this section we're going to set up basic functionality and our client and also we're going to start building our WebSocket server so we're gonna effectively build everything required to connect the client to the server via a WebSocket so let's get started with that so the first thing we want to do is go to our workspace on our whatever you're choosing to create your projects I'm gonna create mine on this external drive here and the first thing we're gonna create is our WebSocket server sorry I work WebSocket client project so we just clear all the cobwebs off the client and this is literally just going to have one HTML page in here that includes our very simple HTML and JavaScript so I'm going to use vs code to do all the cording so just open the S chord as usual and then we'll just open that folder so we have a workspace and then we'll just add a file and we'll call it you can call it anything you like call it WebSocket client HTML and no basically I'm just going to start with a HTML code which will take a while to type and I don't want to cut and paste that I want to kind of taper in step by step so I'll when I get to this point in the editing I'll speed up the coding aspect once I finish the HTML I'll quickly take you through that and then we'll move on to the JavaScript [Music] [Music] [Music] [Music] [Music] [Music] okay so that was fairly torturous but I sped it up for you so you wouldn't have to watch me type it in in real time which would have been very torturous for you the HTML is pretty simple so if you were watching along with that nothing in you know should be too too difficult to understand so let's save it and we'll actually have a look at the file on the page that you get as a result of the cord so if you go into our project me just open this in Firefox and I drag this over here this is this is basically the page that we get we have our connection status we have our connection ID which probably don't have one at the moment we have a input box for our WebSocket server URL which will cord out in a bit I connect button and you can see here the other user interface elements are disabled because it makes no sense to try and close a socket when we don't have one open and then we have a communication log which is basically just going to log all our requests both to and from the client probably the only thing really worth mentioning and will come on to this next is the IDS that we've given some of the HTML elements be make use of these IDs in the JavaScript to change the HTML text for example of the status so it's fairly simple straightforward stuff so why don't we go on and complete the client at the stage of the client stage 1 of the client by putting in the JavaScript so we'll do that now [Music] [Music] [Music] [Music] [Applause] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] [Music] okay so you'll be pleased to hear that was the longest section of typing in the whole tutorial so you wouldn't have to watch anything like that again let me know if you think that's too much and if you'd rather I just cut and pasted cordin I try and avoid doing that because I feel it's not really I don't know it's about one feels like I'm taking a shortcut so if you would rather I did that and find that to be honest with you if I did that I wouldn't really see the point in doing it your tour deal then I think the value isn't seeing me make mistakes cuz I'm sure I've made some and then going back and correcting them so that's kind of hopefully the value that these tutorials brings anyway there may be some mistakes and the chord there may not but we'll find out as we move through the rest of the tutorial and we'll just fix them up as we find them that's fine that's what you do as a developer so let's actually open up our file or page and see how it's behaving know if I can find you know so again I just use Firefox it's my preferred browser I would recommend either Firefox or Chrome edge for me has still a few view of the behaviors that I can't be bothered to deal with anyway the first thing I would do if you're doing any JavaScript programming is open up the web developer tools and open up the web console just to make sure there are no JavaScript syntax errors and that looks ok just a page refresh and that's all looking clean the first thing you'll notice is we actually have a URL and our WebSocket server URL text box and and that is populated through our JavaScript will come with the book step through the JavaScript in a bit let's just see what happens if you try and connect so we get an error and our console saying you can't establish a connection which is fine that's what you'd expect because there's nothing there at the moment and then we get our connection state updated to this WebSockets there's eel which doesn't look too great so let's go back to what chord and we'll try and understand what's going on there as fearless forward to be honest with you there's not too much to to mystify you I don't think so the first section is just setting up all these JavaScript objects that we use in our subsequent functions and enables us to update their state whether they are disabled or enabled and also change the values of the HTML so we can change the state labeling so just before we move through the funk the events let's just jump down to these two support functions that we call throughout the the other functions the first ones escape HTML which takes a string and it basically just replaces any literal strings with the HTML safe equivalent and then we've got this updates the function the lot step through it because it's quite long ball it does really is enable and disable the buttons depending on the state of the web socket connection and I will update things for example the state label so for example when we got that last error if it had been this default case that bit of run and a bit of update updated the state label with this information here okay so jumping back up the first and only event we have wired up on our client is on the connect button on the onclick event again I made a conscious decision not to use anything like jQuery were just using pure JavaScript just to keep it clean we will update the state label to see what attempting to connect most interesting thing really we're doing is creating this web sock object and passing in the connection URL assuming we can open the socket then we update our state and we also update the cons log with our connection opened event as well same with our on Clause very similar we update our state and not their coms log if we get an error then a lot day of state whatever that isn't that you've seen that already running and then if we get a message on our web socket we will display that in the columns log and obviously we're not getting any messages as yet so fairly straightforward to really see if it's working properly we will now create our silver cord next let's jump over to our desktop again and we'll just kill our arch let's just close our client project it's just cause the folder and if you bring up a new terminal and I'll move over to my EFT life which is very storing my projects and we'll create and you dotnet project so we're going to use the web template which is the most basic web-based template they have sort of sets up some of the stuff that we need for us but it's fairly basic and we'll call it something like web sockets so if I could spell correctly that would be even better okay cool and then we'll just open that in Visual Studio called open folder and we'll open up a web socket server and there we've got our empty project we're really only concerned with the startup class let's just click yes for this as we're doing all our work in here for this section I won't take you through the rest of the anatomy of a dotnet core web project if you're interested there's an article on my blog which explains that particular that particular information if you're interested in it I think it's the one on Azure DevOps so if you want to understand the anatomy about dotnet core project read that article it takes you through it there's also a video on YouTube as well that you can watch it takes you through it but we'll explain it as we go through so you're not gonna really miss out anything anyway so start up classes basically supply supplies we're all put our start up cord runs to begin with and we have two main methods configure services we are we add services supply supplies that we want to be able to run make a meal we'll throw the rest of the application using something called dependency injection will cover that briefly later and then I configure method which is really responsible for setting up on request pipeline we talked a lot about the request pipeline in this tutorial but we'll build up that as we move through the rest of the tutorial so let's just take this stuff out it's not really that important and we're going to do all our cording in here but first what we want to do is add a using directive at the top and add our name space system now WebSockets and the first thing you want to do is add WebSockets to our pipeline so we do that by app dot use WebSockets and again I will take you through what that request pipeline is and what more specifically what requests delegates are requests not tell you briefly what they are no request delegates are items that you can add to the number of request delegates actually make up your request pipeline so you can add multiple things to your pipeline and that will intercept and deal with the request and perform some logic on it or not so by adding WebSockets type Oakland we're giving it that capability what we're going to do now is basically add our own request delegate that's going to allow us to connect that way absorbtion we do that with the app dot use syntax and then there's a standard signature for a using request they're getting those three types of the quest delegate that'll take you still with the are but we were going to create a user request delegate and that requires a context I can spell that connect the context object and the mixed object and we will use this context and this next object in this request delegate so the first thing we want to check is we want to check the context so it's basically checking what is the context of this request pipeline and the first I'm going to check if it is a WebSocket request so you'll remember from our overview of WebSockets that actually starts with a HTTP request upgrade the connection to WebSocket so that's what this is here it's actually checking to see if we have a WebSocket connection request EPS or then we'll do something before we deal with that if it's a lot and all we do is be a wait the next request delegate and again I've got a slide that explains this but basically we could as I said we can have multiple requests there that gets in a chain and so what we're seeing here is if it's not a WebSocket request then just go to the next request they'll get in the request pipeline as it stands we don't have one yet but we'll play around the fat in a bit so that's all that's doing if on the other hand we actually do have a WebSocket request then this is where we want to actually do something I will also come on to async in a wait later and that got a section on a synchronous programming in this talk it's actually really important when we're talking about things that WebSockets that you know what async in a week are and you'll see it used in the chord we're going to right here but I do explain what that is later as well it's effectively how we do a synchronous program or how we can do asynchronous programming in dotnet or C sharp so if we do have a WebSocket connection request then we create a WebSocket object assuming that can type it correctly imma call it something like where to stop it and again we're going to use this a weight modifier here and we're going to wait [Applause] not doing that one I'm going to accept the WebSocket connection and we'll do a console.writeline just to see that it has in fact okay [Applause] so again just to take you through what's happening by checking to see we're looking on a context object more checking to see if it's a WebSocket request if so we create a web sock object-- I mean use this a synchronous path on here that's repeated throughout this tutorial Priya wait which is basically saying can we know that something's going to take a while possibly to connect so let's all wait it I've taken you through what actually happens when me await something but Park that for the moment so we are wait on this method to your basically and again you can see it's in a synchronous method sort may take some time to to the tongue and it's basically just saying yeah we're going to establish the WebSocket connection not lead to a WebSocket session and if we are successful then we will then write that out to our console log let me just put a semicolon and then I think we will be good to go so let's save this okay so that's the end of our salvar build fault for the section um so let's let's see if it runs or key and let's see if our JavaScript client can connect in so back over in our project let's open up our terminal window and we'll build it first of all to make sure it's building we've got net build zero errors and zero warnings that's good and then dotnet run and you can see here it started on localhost port 5000 therefore using HTTP and 5,000 won for HTTP and that's configured in launch settings Jason here if you're interested in that so that looks at that's running okay let's move back over to our client and all open out unless we have an instance running we don't and we'll run that in Firefox and again it's always useful to open up the developer tools web console just to there's getting a bit crowded because I'm running at our law resolute well not magnified the resolution at 150 percent so you can see things more clearly and but we're getting a bit crowded nonetheless let's see if you can connect and well it's just yeah that's you even connect them cool so we've got connection opened we get no arrows down here but I was just expecting something else to happen here and I think there might be an issue with our client so let's let's open up a client project just because I'm expecting something to happen there that didn't happen ah okay so we called this socket open up this socket open event occurred because we opened our socket I was actually expecting to get a closed event as well and I was wondering why we didn't and I'm realizing though because we've got off an error here so it should be that so that this was not fighting because I was expecting it to fire so let's save that let's reload this okay so let's try again yeah that's better okay so you do get a connection so the connection has opened and you see that it was opened down on our server your web socket connected that's cool but we then almost immediately get a connection closed event as well with us one or six chord which from memories something Lakers I can illegal termination of a connection or something like that can't quite remember what it is but it's not good basically and the reason that's happening is because our web sock object is quickly going out of scope so we did create it but then almost immediately it just gets closed that it dies because we're not persisting it we're not keeping it open so that's what we'll do next okay so we've done some chord and move whether you realize on a lot I think I've have mentioned that you've created your first piece of metal will end the request pipeline but I wanted to delve into that just a wee bit now just a theoretical perspective because it's something I feel you really need to understand we could gloss over it I think if we did that you wouldn't understand WebSockets quite as well so what is the request pipeline well on screen here this diagram is lifted directly from Microsoft the request pipeline basically comprises multiple pieces of what we call middle wheel and the will jump back over to the chord actually what youĂ­ve written in our code this here this is a piece of middleware as is this okay and so everything configured within here is basically a request pipeline okay so there's a request pipeline there's multiple bits of middleware request comes in and it propagates its way through the middle wheel and returns back theoretically so comprised of multiple middleware components the decider requests will be handled we build middleware with requests delegates or again that piece of cord I showed you that as a request delegate and we can see different types run and they run at the end of the pipeline you would put a run request delegate at the end map is used to branch the pipeline and use can short-circuit the pipeline so we've created that you use request they look at again let's just pop back although in this this is what we see here so you can either have a pew zap run Matt we've got an app use and let's go through this example again on the slide just to show you exactly what this happening so skip through that okay so this is what we've called it so we've added two bits of metal wheel here we've got app use WebSockets which is about the box request there like it you get with WebSockets and then we've created our own request delegate app use context and next so happens a request comes in some logic is performed to you we then come into our custom request delegate and we determine if it's a WebSocket request if it is then we kind of we do what we we do the call we await a connection and then we return back through the request pipeline so when we see short-circuiting this piece of custom and middleware or request only has short-circuited the pipeline and returns us back through it if it isn't a WebSocket request then we come into the else statement and we will await the next request they'll get in the pipeline and it just so happens I've just put the a double coming in and back out again there isn't one and then we just come back through the pipeline so you have logic before and logic after you you propagate through the pipeline and then you get your response so the idea is you build up actions on your request and Microsoft actually recommends that you add middleware and a certain particular sequence depending on what kind of thing they do so I've put links to that in the description below and also on the blog which will take you through their recommendations they are so what we're going to do now just to illustrate this point is we're going to add another a customer request they'll get a third one at the end of our pipeline and you'll see how that behaves now all it's going to do is just print something to the screen it's not going to do anything valid it's just to help you understand request pipelines so we're going to come on it and we're going to do that now so the first thing we're going to do is add a request a third request they'll get into our configure our method after the two requests delegates we already have so we're going to do run this time no just going back to our Slade wheel you'll remember that we can have three types of Delegates and anything any request area that users run this runs at the end of the pipeline so what we're really saying here is we this is we expect to be the last daily get in our pipeline which makes sense use the async key bottle as well because it's an a synchronous operation and we pass in the context before which is just request context you'll notice for not passing in this next task because it's the last delegate in the pipeline we don't need to pass on that they oughta wait on that as we did with the other ones okay which kind of makes sense so let's just write up our code and it's fairly simple well I'm gonna do two things in here the first thing we're gonna do is just write over to our server console just so we can see what's going on and we'll just say hello the request delegate and they're not going to actually add something to our response so we access that via context find our response and then we're going to perform a right and you'll notice it's right a sink so again it's in the synchronous right and we'll come on in the next section to talk about the synchronous programming for no just be up with me and what I'm sure will just copy this just copy this text yeah no you may be a bit confused between these two things this one here is really just writing out to our one thing this one here is just writing out to our server console this one here is actually writing this string to our response via the request pipeline you'll see how that works in a bit and then all we're going to do in here another console on today I'll just copy this one thing exactly the same thing will just update the text from the second request delegate so again here's a foster crest delegate that will run we then come on to our second request delegate that we ran the route in the last section if it's a WebSocket request then we do something and me basically short soft at the request pipeline otherwise I guess we assume it's a HTTP request and be right there so to the console and then we call our next request delegate in our pipe language is just basically gonna do this stuff here so let's let's test that notice let's do let's make sure to receive it and that's run so again as before we'll just try a WebSocket connection that's all what can we get the connection open then immediately the clauses will deal with that later and we get the WebSocket connected message that's fine that's what we expect you'll notice this doesn't run and this doesn't appear too angular which is correct so let's get these elements to run and this is just showing you how the request pipeline can operate in different ways depending on what's been passed into it so let's open up another tab and we will go to our local host on port 5,000 so this is not a WebSocket request it's just a regular HTTP request we have a ton we get this law from the third request delegate which is this line here and then if you look down at our console you can see this was triggered and of course this was also triggered so that's just demonstrating how the pipeline can change depending on the request type so just to illustrate that we pop back over to our slide we are and I've got a final slide on this here here we are here's of the quest delegates or request comes in the next method gets called in the first one if again it's repeating what I've seen before if it's sort of a WebSocket request then we shot socket that grasp a plane and Vuitton if it's not then we await the next delegate where we have done all right line stuff and blah blah blah you've seen that in the previous example and it will return back through the pipeline and you've seen how that works the example so we'll leave the request pipeline there for now I think that's enough detail to help you understand how that is working and it's a very important concept and again thing to take away is take away as that is all set up within the configure method on the startup class all right now just before we get a couple of things to finish off in this build section it's probably the longest build section in the video so I'm just going to cover off what the request handles look like at the cerebral end so we've talked a bit about this concept of a HTTP request being upgraded to a WebSocket I just want to show you what that looks like in the server and to do that we're going to write a little custom method it's quite simple just to print out the request headers basically so if we pop back over to our application we're going to write that out now it's purely fairly straightforward so the public Boyd might requests and we're going to basically pass on a HTTP context we'll call it context cool so basically the same thing we've been using up here I'm just going to pass that in and we're going to print out various and properties of that HTTP context so we'll print out a configure console.writeline we'll print out to the mean attributes before we trim the headers so request method let me some access it by context request method don't know what happened there okay and let's just copy this and they'll also right over the protocol so you can see what's happening there cool and then we'll just print out the headers so in order to do that we'll just check that our headers object is not null it shouldn't be it's like checking any assuming the lock null let's look random so for each page in context request headers you'll just pin them to the screen sort of console.writeline will just indent them no H key accessing the key attribute and then the value so the basically key value peels each value save that and let's not forget to call this from we'll call it from our second request there we go just to see what's getting past then at this point request plan I'm just passing over the context quite simple okay now you don't need to do this again this is just to hopefully extend your learning we've saved that so we'll do a dotnet one and let's just refresh this and let's connect on our web socket so you can see here we've made a web socket request our method was get a request protocol HTTP you can see there's a lot of other things down here and you can see there's this upgrade key to WebSocket request and there's also I'm sure yes here in this connection we've also got an upgrade request here along with some other stuff the only other thing I'll just get you to pay your attention to is this origin key here and the value of null now what the origin is because this is important a bit later on where this client is running so if this was actually running on our web sailboat it's not we're just looking it as a file in the origin you would see HTTP you know google.com over here because we're running off a file the value is null so just Park that for now if it comes back a bit later when we talk about signal art and we'll circle back to this as well all this conversation here but that's it for the section was really just to show you the nature of the upgrade request and the HTTP headers and how we establish a WebSocket connection so next we're going to just do a bit of an overview of asynchronous programming and dotnet because the next section of code we're going to write the next section of code we're going to write relies fairly heavily on it so you should really understand how that's working slice let's do that now okay so we move on to a bit of an overview on a synchronous programming in dotnet now it's a pretty large subject area and I don't want to go into massive amounts of detail because it might derail us a bit too much from the main point of our talk here which is WebSockets but I felt it was necessary just to provide the one page or on what a synchronous programming is because it does feature quite a lot in our video so you really need to understand what it is so if you do understand that this section won't take too long if you don't understand it hopefully this will start to help crystallize what a synchronous programming is but why I'd also recommend is that you pop over to the Associated blog article and I've got a link in the description below and there's two articles that you really should read if you've not done this before and one is about the synchronous tasks programming model so it's more about the theory so I've got an overview here that goes into a bit more detail and then there's also a really good article on the flow of control through a synchronous code because it can get a bit confusing because you can a jump around from place to place to place but there's a really good example and with a worked example that you can follow through it and it will help you if you've not done this before but anyway back to our overview slide simplest methods use the async modifier so you'll notice when you define an a synchronous method you will use async as you know one of the modifiers synchronous methods will usually return a task tasks represent ongoing work and will eventually return with your the result or an exception so as we said before with the sinkers methods generally you expect them to take some time to complete so it's usually long-running methods like stuff all but I'm at work we really have no control of it and you expect that it may take some time so what you would typically do is you'd kick off the the method you'd call the method and you would wait for it and you want a bit what what I mean by that you will wait you wait for it to the time at some point in the future in the meantime you can potentially go on with other work some things you can there's some things you can and most usually a lot of the time it's used to stop the user interface from being blocked so even if you're doing something in your waiting something and the user interface is still responsive so it's often used for that and but also you can kick off other processes at the same time you know at some point you mean to bring everything together at one point before you can continue on but that's getting a bit more detailed we don't really need to do that here but we are using a synchronous method so it's useful that you understand how they work so yes a task is the thing that you will await on when you call in a synchronous method so just a bit about naming conventions or synchronous methods will usually end with async so that gives you a clue as to the fact that there are synchronous methods and then a wait statements can be used to basically call those are synchronous methods when you need them and what they what they really represent are suspension points so basically we're going to call it a single in this method we use the await keyword to call it and basically what that saying is we cannot continue past this point until we get the awaited process complete until the task is returned back to us so when you talk about synchronous programming net you'll often hear away async await there's a pair of keywords that you'll use and that's basically what they are async is the modifier on the actual method and a weight is the keyword that you use to call that method and a wait for the result basically it I'm fine when awaiting the control returns to the async method so well we've kicked off a process and going okay I'm gonna wait for this to come back the control returns back up the chain to the method that called the same process and potentially you can continue on with something else if that is the case so that's basically synchronous programming and a nutshell actually brings us to the end of our build phase one where we did quite a lot work and it covered a lot of theory you'll be pleased to hear the subsequent build sections build phase two where we send and receive messages it's less theory more coding where we start to embed the concepts that we've gone through okay so don't phase two it's a lot shorter than the phospide the build phase where we actually clammed a lot of stuff and we're gonna work on a both our client app and/or server app basically Telo to the same thing of messages so it's not wait any longer let's let's delve straight into so let's that sort of Salva raps let's kill that and let's open up our client app you just do maximize this so this will be familiar to you're not going to obviously go through the court again so the first thing we're going to add is an event onto our close button so we've got our connect button I'll click event we're going to add a button for our close button close button on click running a function on that and basis we're going to do a quick check on our soccer object we can spell it correctly so first I'm going to see if you don't have a socket or and the syntax interestingly is very a can be based similar to C sharp so it should shouldn't be too early into you or the socket ready state is not equivalent to web socket open so basically if you don't have a web socket or it's not open then we're just going to fire out a layout which is basically a box that can tell us something we could wait it to the console but I think we probably need to wait out to the user and stop you're not connected so because we're all main ting are you by using the update whatever that's called you know so yeah the update statement that we shouldn't get this but you never know this was just checking anyway assuming it is okay then on a socket we're going to call Clause and with a method of record of 1000 calls and complying and basically that 1000 cord is basically seeing it's a clean enclosure request for mark line everything's everything's fine and then we are going to the only other thing we're going to do is on our same button again wide up a non click method to send a message and declared a function and we're going to do a very similar check if we don't have a socket or the socket readystate not equivalent to web socket open then again we're going to write out I shoulda just I should have just cut and paste action I realizing it's exactly the same cord let's just do that then saves you watching me typing okay cool however shimming we do have an open connection we want to then send the message we need to clear a an object called data on a variable called data and that's going to be equal to a the send message text box will be having that the value of that and then we're simply going to want a socket call the send method now you'll remember from our web socket API there was two methods send and what was its end and open that's just a quick check yeah sending Clause okay so we're going to send some data over our web socket and what we're going to send is going to send this disability really straightforward and then we're going to update our communications log so I think I can probably yeah let's copy this code here I think that will be sufficient I might just have to editor okay now we won't use Advent D thought because well operating off of em but it's gonna pass in this data so we're just escaping the D terminal up the it becomes lock that's it that's a climb fairly straightforward so why I've got per close button to issue a clause a method call passing it a nice clean cord of 1000 I'm also wiring up our same message button and passing in the data that sent us a message text box and we're just escaping the HTML data so that all looks good let's move on to our selves on low alright so we're going to move on to our cell block employment and we're going to write a synchronous method to receive any messages on our web socket and it's also going to resolve the immediate closure of our web socket because we effectively go into not an infinite loop the bar a final loop that just exists under the condition of the web socket being open so file the web socket is open we're going to be in this while loop because it's in a synchronous method we can pass control back to other parts of the application so we're not blocking it it's arguably what's not ugly is the the most complex difficult to understand bit of cord we have in our application I will just show you again I'll try and explain it as best I can and in the video but I do have full cord have a full chord in the blog and also with full explanations of what is going on in this method that we're going to write this receive message method it's quite tricky to understand but I explain it and fill here and then just following on from that actually go through the synchronous method calls and what actually happens each stage because it's it's quite tricky and but there's no way of getting around is what it is so we'll go through it here in the video but just be warned that it's quite quite tricky so back over in our selves our cord just make sure you add this using directive that wasn't there previously using system threading we're going to write up our receive method or a synchronous receive method so private synchronous so synchronous modifier it's going to return a task and I call it receive message and it's going to expect two things it's going to expect the WebSocket or the socket and then the next thing that's going to require require is something called an action delegate in an action delegate is almost what's Knolls that is it's a method that you can pass to inter method and it can also pass stuff back out so field cleared with this action keyword action delegate and again in the blog of a link to what action delegate so I explained a bit and what about it and we're going to expect a WebSocket WebSocket receive result along with a byte array which is our message I'll call it so let me write the rest of the cord before I try to explain it because as it is that will probably make absolutely no sense to you so let me write the rest of the cord and then we'll step through it and hopefully it will make a bit more sense when we do that so within our receive message we're going to know just just an interesting point of law you can see that we've declared our a Sinkin in this function and we're getting this this complaining message here and people look at what that is seeing this ecig method elack's and wait operators and we'll run synchronously okay so within our async method we expect an a wait operator so it's not going to stop the compiling but it's just saying you've said this isn't a single in this method and it's not yeah it's not it's not synchronous basically and or what and synchronously so within it we're going to declare a buffer and this is how we are going to get the message within our web socket and it's just a battery basically and again this kind of talks to the maybe the WebSocket protocol and we'll have further information on my IV to clear it in this way but for the moment we have a byte array that will contain our message string and then as I say we need to enter into this while loop while this socket state it's according to WebSocket okay so while the web socket is open that we've passed in here we're just going to keep looping run okay okay so the thing off I'll look we're going to expect the result back from and a synchronous method defined by Microsoft on the soft object so they have these two methods receive async we receive messages on the socket and send a sync we're going to use receive async and then looking at the method signature basically references the application buffer that is a story it'll case even for the received data okay so that's all it is and the way we receive the data is by defining a new array segment type bite pass on our buffer it's gonna be bit annoying maybe ovulate it and then we also pass on this cancellation of talking I just said okay and then finally we call our handle message action delegate back with the result and the buff on this action delegate propagates it back up to fear the method is called which we will do now so let's use this method and then we'll step through the cord because it is a bit is a bit tricky so back up here we're going to go into this section here where we await the connection of our socket we'll leave that here we're going to begin after here so we're going to make you snow of this away of this of this receive message method here we're not a weight on it so again he synchronous programming and we're going to pass on or WebSocket and then we're going to use our action delegate here we call it a synchronously and we're going to pass in result and a buffer don't do that so again missus this is really a lambda method but we're using these two components here so we call the receive message we pass in our web socket and then we call our action delegate I'm it passing or we expect back actually a result and the buffer that's received so these are actually items are going to be populated to print this handle message eventually returns so we call this method synchronously we wait while the socket is open and then if we receive something on our socket this method will trigger and it will call our handle message action delegate with the result and the buffer which will then and tunnel return back up here and are then going to process the result in here so hopefully that made sense is quite difficult to follow and I'm having a hard time trying to explain it so we'll see it working that might help read the blog article that might help both step through it one more time wants to finish the cording and it might start to settle into place for me actually it took a while for it to kind of fit into place so I do not so if you're watching this and going what you're talking about I don't get it I don't blame you okay because it's tricky so follow along with the chord gain it working and then it will eventually embed I promise you it will so effectively what we're doing that as we've we're going to have our callback from a received message method I'm not going to check to see what kind of result we get so we're going to interrogate the result and we looked at something called message type and if it's a credible to web socket message type which is basically a text message then we're gonna do something else' it can also be a clause message so if result message type is equivalent to web socket message type Clause then we're going to do something we should do something else so in here if it's a clause message we'll just simply for the moment we'll wait o to the console closed message leave the tongue and here if we get the capitalized that's why it's complaining if you get do actually just assure you the different message takes we can get our text Clause and binary so you can receive a binary stream as well but really we've been only deal with FB get a text type of message result back then for no we're just going to write out because there's a lot to take in here and I don't want to go too much further message receipt correct that okay now you can see that this is complaining as we all know if you just let's just build it sieve it build we get two arrows like selected what those arrows are okay and even just get some syntax longer some mail they didn't know that is up here okay I think that should solve that yeah okay cool let's just say that again build it one more time cool so we get a warning right and we'll clear this warning up later on but basically you're calling our action delegate asynchronously which is the right thing to do but within but then the cult of it which is effectively and here there's no await statements and here sort of saying the same thing as we had before that this async method lacks and the wait operator sort of on synchronously that's fine it will run okay just now so just to try and step you through this again if we have a WebSocket connection then we attempt to connect it and we await on this asynchronous accept WebSocket connection method here we then have a connection we then await on a socket to receive a message so we jump down here and to our receive message we declare a buffer that we expect to be populated with any message that comes back and we enter into this while loop that remains open while the socket is open and again we await on a method on our socket for any messaging that comes in on that socket if we do get that then we end up returning back a handle message action delegate which then pops us back up here and we then check on the result of that now this just keeps running and in a synchronous fashion so that we can do other things that's the whole point of a synchronous programming again over here in the blog I do actually explain it much better I can write explanations better than I can explain them verbally as I'm sure you're starting to realize I do actually take you through what's happening in the cord okay so let's try and run our cell record and see if you can send a message from a client to it so dotnet run to run it up I've got an instance of a client you know that's just reloaded so we'll connect in okay so our connections open we've got our message to our columns log but one thing I'm just noticing we can't send a message because our UI elements haven't updated on our client so there's obviously something clearly wrong with our client so let's go and have a look at that what did we do wrong what did I do wrong so let's look at our update state function and I think I see what the problem is I think rather than this being disabled I think this should be disabled with a D I think that's a issue so let's so if we go into our switch statement on open we should set our state label to open then that happened we call the enable function which is this so I won't update these let me just update these to see if that makes a difference so be lured so if we connect cool that has actually what this hasn't what those still okay so we've got a bit of a problem there let's let's pop back over here there never look and make sure to get everything yep so let's update all these disabled and here okay so again that this is a reason and it's because I'm a bad JavaScript programmer up at my hands up to that but it's also a reason why I hated Nikolas it wasn't Aaron I know it wasn't giving as any issue for me javascript is just I don't know it's just stuff like this kind of winds me up anyway hopefully we've caught everything there and okay I don't know why but I think yes if not and everything we need in a default statement so that should disable everything really and as well okay so I think that should be as fixed wet so refresh so yes we're testing our what send message functionality so let's connect and cool so that's disabled now okay let's just put a message on any old rubbish click send excellent so we know received our message now the other thing that you would have noticed when we connected we didn't immediately get a disconnection and that's because we've entered into this file look well the connection is open but it's also open in an asynchronous way so what that means is we can also put our local host request and on a HTTP connection I can get my act together hit the right key on my keyboard so again it's running asynchronously we can still put HTTP requests through the request pipeline and our WebSocket connection stuff is still running so yeah it's all good there we've got output from the console from our request we just meet here and theoretically we could fire up another client in fact this let's do that I'll put the Firefox and we can connected on that we get a WebSocket connection and you can send messages on that cool so that looks like everything is working we are sending messages we're not yet displaying with that messages but we are receiving messages on our client and we are receiving messages on ourselves or former client and the connection is staying open in an asynchronous way all right so we move on to phase three of our build and in this section we're staying completely within our selves our application and we're really going to just upgrade Missy just we're going to upgrade the middleware that we've already written and spin out intercept class so it's not really going to impact the functionality that we're developing but it's just going to make our cool cool it a lot cleaner and adhere to can have some fundamental principles so it's definitely worth keeping in so let's move back over to our server application and the first thing we want to do is add a full dot the root and I'll call it middle wheel student we can spell it correctly and I always seem to capitalize the the I so let me go a little bit off all that and then here we're going to create a new class and we will call our class web socket server little we r dot CS and supplies that didn't actually put in a namespace for us unary WebSocket server little wheel save that okay and we'll add a few using directives at the top that we will require to get this up and running system system dot net WebSockets system text system reading system loading tasks and then finally not-not-not system microsoft asp net core HTTP so our class is public that's fightin first thing we want to do is create a private remember variable read only and this is actually our request delegate that we need to define an order for this to work so basically what we're going to do is we're going to replace this with something like this and by spinning out interceptor class that's enabling us to do that but in order to do that we need to set up some scaffold to type cord if you want to call it that in order to get this working now again on the blog article that is a links to some Microsoft documentation how you should structure your middleware classes and it follows a specific standard pattern and this is basically the pattern I'm just following here so then next we want to create our class constructor weird socket serve a little meal and we pass them via dependency injection or request delicate and we assign it to our private instance now again dependency injections are huge easy on it's all made a video and that at some point but basically via our configure services method although it's not specifically defined here it is available to us through the pendency injection we will get an instance of request there will get passed in and we lost saying it before you see you well come on to drink a bit more about dependency injection a bit later on and we actually utilize other in a bit more detail and then this is our final thing we need to wire up is really a public invoke async method which is a synchronous with tons of tasks and we'll call it invoked yes easing and that accepts HTTP context now that is basically our standard pattern setup and all we're going to do in this method here we're just really going to cut and paste the code that we already have from our start up method here so basically just copy all of this yeah and paste it into here I'm again an error because we don't have a receive message method so we will need to copy that over as well so we come here and we've cut that out and paste it over here now instead of a waiting mixed people a beat on our private instance and Passover our context so that we will call the next request a legate and our pipeline if that's required so let's save that and see if I start up class and in fact we'll take this out as we don't need this see then the only other thing we're going to do in here was if you recall when we received the message we didn't actually display the message on screen so that's well we didn't display it within our console log so we're going to change that now and just write that out to the screen so it makes it slightly more useful so we'll just write out our message to the console using our right leg method putting our message and we're using this dollar sign which will allow us to interpolate our variables within our string and it will print out it will display it as a string so unfortunately we've got to use this we've got our buffer and we need to basically decode it using utf-8 so we take our buffer start at zero and go to the end by using the current length I should display it hopefully so the way that we can reintroduce our middle way our entire pipeline is to expose it through an application builder instance and the way we do that is by creating another class in our middle we are folder so let's do that now and we'll call this one WebSocket this is either getting quite long these names set up a little wheel extensions dot CS okay so I created a file that time rather than creating a class which is not coming of ins the basic stuff that we require but that doesn't matter so the only using statement we need is Microsoft asp.net we'll build up and our namespace is WebSocket server little well and our class this time is actually going to be a public static class so you don't have an instance of it it's just a static class that we can use off the bat and we'll call it web socket server level they are extensions and then basically what we do is we expose our middleware class through an application builder instance we gain public method static and again if this is a bit confusing for you I'm not going to go into too much more detail about it read there's a link to a good article from Microsoft in the blog about how this all works but basically we're creating a method static method that we can use in here so you can see this one's called use WebSockets if you go back over here to a middle bit we're going to create something very some one I'm going to call it call what we like use web socket server and that method we can use via this static instance the static method call we merely pass in our application builder builder and then all we do is read ton builder use middleware won't be going to the ton back and we're going to return back one of these here so let's just copy this and to make sure there's no mistakes cool so we save that and hopefully if you've done everything correctly you know that we do a dotnet builds I don't need to be able to spell it right should be okay you'll get that warning seem warning it was just moved into a different class above synced in this marathon running synchronously but that's fine we can ignore that for just now let's run it and so we should see absolutely no difference in how our client behaves against that it should just be exactly the same and not changed our client but if ever things running as it should actually this won't work for these for a very obvious reason if you go back here we haven't added it into our request pipeline so let's do that do let's just stop that and come back over to our startup class the first thing we actually need to do is either using directive to our middle way or fall down so it's just an internal reference kinda but referencing the WebSocket server middle we are namespace and then within here we want to find this method this method should be available to us now so at use WebSocket server it as its there now if all is working correctly then we should be able to run this 11 as we've got trying to before before we before I forgot to put this in so let's save that and let's just do a build ok and then right ok let's just restart our this we start our WebSockets and bring up our selves and actually so they can see what's going on and there should be no difference connection opened actually there will be a difference we can be able to see our message now should be display the feedback correctly there we go cool so message being received as before but this time we're displaying it on to our console so that's the end of this build section it was quite brief but if there's a worthwhile taking our little request they'll get in moving it into a separate class because I'm sure you'll agree this looks much nicer much more professional No so section done let's move on ok so we're moving on to phase 4 of our build which is adding a management layer to an application now what do we mean by the applets let's demonstrate what we mean by that so we've got and I've got two instances of our client up and running but not connected yet to ourselves off so let's do that now so we've got two connected instances of our client which is fine and you can even send messages so hail from one hello from one saying welcome to fit so that's not working and in fact we've actually used everything that there's to use on the web socket API so relatively simple API so the state and we've got this kind of central salvat as a hub and then we've got multiple client endpoints all connected in but they're on a weight of each other so what we need to do is add a manager a class to basically allow us to perform some voting and more special especially identify the client in points to a low for that routing so we're going to introduce a manager and as part of that manager we're going to track our connections and give them a unique ID that we can then use to perform some kind of routing functionality so that's what we're going to do now all right so let's move over to our server application we're going to add on management class which will do two things that will generate unique ID for us for each connection and it will store that connection against all our WebSocket connections so we can put this class anywhere we like I'm going to put it in our middleware folder just probably is a bit neater and tidier in there so a new class and we'll call it something like WebSocket see how about connection manager not something like something exactly like that so that's added in this add-on namespace WebSockets a little we are and we need a few using directives in order to get this all up and running so first one is using system second one is system collections concurrent and the reason we need that is in order to store our WebSocket connections we're going to use something called a concurrent dictionary object which is why we require that using statement and then finally system dotnet WebSockets so let's create our concurrent dictionaries apply the instance and it just stores key value pair so we're going to store what a string which will be our unique ID and then our WebSocket I'll call this sockets so create new cool alright okay so we've created a private instance of our conviction we want to expose that as a method the public method so we'll call call it something like get all sockets or what we want to a ton as a confectionary of string WebSocket and we'll call it get all sockets so this is just as exposing this private instance to the rest of the world and we're simply just going to return sockets cool and then the last thing we've actually want to do is add a method called add socket that will allow us to use this manager to add sockets to it and as part of that methods will generally a unique ID for that socket it's pretty simple but necessary okay so make it public we'll make it a ton of string which will be our unique ID that we generate and call it add socket and we'll expect a web socket so let's create a string called corn ID and we'll generate good the gooood is just a unique identifier you'll have seen them around I'm sure in fact well you've seen it at the dam or at the start of the start video and we'll just convert it to string so we create ourselves and you goo it and we'll store it in here and we will return that back and then between the timing it back and generating it we will add it to our dictionary using the Triad method so try a link on ID and the WebSocket that we passed in and just to make sure for our own sakes that we believe it's working we will right out to the console log something like connection added I pass a look at white save that and then we'll build it okay so we actually want to use our connection manager in our code so we will pop back over to our website see what middle we are classed as that's where we're going to make use of it and the first thing that we want to do is create a private instance of it that we can use or private read-only WebSocket server connection manager and we'll call it manager it calls in you so just before we move on you know we we've got this you're instantiating a request they look at this and because it's available through dependency injection we can set up through our constructor in this way what kind of using a different method now by using a new statement to create a new instance of our WebSocket server connection and you'll watch I don't really like but we'll circle back to that in a bit enemy if we've got our manager up and running and so what we want to do is after we have connected we can just call the add socket method on our manager but what I also want to do something I want to use it later I'm going to create a string call it corn ID and we'll pass in the return value from ad sockets that's socket you know city and I'll pass in the web socket so just to go over that again if you pop back to our connection manager class we actually pass back the caller ID that be generated I'm just putting it in here because we may want to use it later and we're adding the web socket that we got connection on so let's save that let's build it and let's run it and what we should see every time we connect in our WebSocket should get added to our manager and will get a unique ID so let's just bring our clients back up and or brief I don't really need to be flash because they've not changed but if we connect matter we have a connection added for this connection and reconnect on this one we will get a separate connection ID on this woman so we're still not there yet but we're moving towards tracking our client in points via unique Goods so we're stepping towards being able to row between clients but before we do that I just want to tidy up our connection manager chord so going back to our chord over here what I wasn't too happy about was how we have and how we've created our private instance here by using this new keyword I would like it to look a bit something a bit more like this but in order to have it look like this we need to use something called the pendency injection and what that means is that we basically tell our application where it can get an instance of this class without having to explicitly create it like this and we can even take it further and by using things that interfaces that I'm not going to cover so in order to do that what we have to do is if we go back over to our middleweight extensions class where we have our application bill we have up so you have our user WebSocket salvo don't want to do that method a returning an eye application builder we're going to add another method in here that we will basically put into our configure services method now just refreshing your memory I can speak of services method that's where we set up services or dependencies that we want to use through our app now some of those dependencies are created out of the box we don't need to do anything and some of them like the dependency we're going to create no and for our connection manager we will have to add here explicitly so in order to do that before you go back over to our extensions method class we're going to create a method of all of us to do that so again public static and this time actually before we do that we need to add a another using director and it's in your action and we want to create a nice syllabus collection and like how we created this method name here that we can use the Austral and application the method name we use here we can refer to in our startup class so let's call it something like add web socket keep it a bit keep it a bit more brief than we have some of our names and you'll pass in this or basically adding it to the existing ICS collection for services and we're going to see services now you get a number of options here that allow you to register your dependency in various different ways I have put links again to in the blog we were going to use add singleton to add our manager class to our services collection make sure we add the right class web service connection manager and we'll just return our services collection little bit added this too so we'll save that and then back over on our startup method we can actually use it and if you just tabulate it we should have it here we are add WebSocket connection manager and also basically what that's doing is it's calling this method here am i adding an instance of our WebSocket server connection manager as a service that is available for use throughout the rest of the application so what this means then is back over in our middle wheel we don't need to use this we can get rid of that because our application already knows what it is and it doesn't need to actually explicitly create it using the new keyword but what we do need to do is we need to add it into our constructor here because that's where it's going to get pushed in so we're going to push in a WebSocket server connection manager and we'll call it manager and then and it's seen me that we've defined our private instance next we will define our private instance manager with whatever is being pushed in via our constructor to manager so again dependency injection I found it quite difficult after that actually difficult when I was learning about it it was quite confusing and I went against other thing that I came in new and but once you get it it is actually very powerful so just to reiterate we have set up this static method called add WebSocket Manager it adds it to our services collection and then we can reference that and this way here by using dependency injection and using a private member that be and we assign via constructor dependency injection and also all our startup class we have to add it to be available know if this was not here then we would have some problems so again you can save that and we can hopefully run that and it should work so again it's not changing the functionality of a chord but it's changing the maintainability and the readability of our chords let's just refresh this connect yep and they're getting exactly the same result okay so before we move on to the next section which is adding up oh it's our one thing we still have to do in this section before we finish it off is pass back the connection ID to the client so at the moment client connects in the server generates an ID and adds it to a collection of connections that's all great but the client is still totally unaware of of this connection ID which it will require an order to basically but we will require an order to perform routing so back over on our chord let's shutdown ourselves if it's not already shut down and we want to add a new method into our website itself a middleware class which is basically where all our functionality is the majority of our functionality is no sitting so we're going to create another synchronous methods you won't be surprised to hear will make it private this time because it's just for use with our selves oh and this should be very familiar for you know with you this should be very familiar for you know using the async a keyboard and also or tonguing a task you said we'll call this send one ID and then we'll put a sink at the end of the name ticular maintain the naming convention we'll pass on a WebSocket or a socket and we'll also pass on the corn ID that we want to send back and this is going to be relatively simple you can see here that's complaining again it's coming as a scene complained of defined in a synchronous method but we're not using any await statements in it but the first thing we want to do before we do that is create another buffer and we're just going to encode our string so that we can pass that buffer in the next following method so we'll use encoding on cooldown including utf-8 get bytes and then we're going to encode the following string Carnegie just as I kind of static not really ahead I've been just stuck in a prefix to what we're going to send over because we will be using this on the client side and then we'll pass over our own ID and then we want to basically take that buffer and pass it over to us well send it to our client via the send a sing with it's already used receive a sync this time we're going to use send async and what do we send we send over the buffer we've just created a socket message type text indicates whether the data in the buffer is about the last part of message a true and then finally the cancellation talking and that should be enough so that's our send corn ID async method which we will call to send our connection ID back to a client so to make use of that we will go back up to our main invoke async method and after we have added our socket to our manager we will call this method and send it back so we want to wait on it because it's an a synchronous method and we do is send one ID async and people pass in our current WebSocket that we are receiving messages on not receiving a connection on janessa sorry I will pass over the corn ID that we have stored from our previous operation here fantastic so let's save that off and what we should be able to do if we control C on this did a dotnet dog okay and then donate runs what should get it now on our client we don't get into the fashion but refresh anyway is when we connect we should get a message back from ourselves off with the con ID and indeed we do so we have now received a message back from our Salva telling our client what connection ID it's been granted and as you as you can see here they match no surprises there so we could leave it at that and in fact we yes we could leave it at that but we warn one of the things I wanted to do was actually pass the corn ID and display it on on the screen in a in a slightly nice obvious or next let's do that now so let's move back over to our client cord and we'll just update that so that whenever we get a string of this format we will populate the value of our con ID so let's move back over to our client application here we are and we want to add in first of all we want to add in a new support function so here are all our support functions we're going to add another one in and all this is going to do is it's going to look at string and trying to tell me whether the message is a connection ID message is quite good I'm going to actually going to change our messaging in the final build section build five but for now we're just going to do it this way which is fairly basic but it works so we will create a function will call it as carne ID it'll accept a string and then all we do as we determine F string if the substring of our string and we provide a start and an end so we're going to say Z between zero and seven is equivalent to corne ID cool so basically popping back over to a server app here yep when we creates to get the right place yep when we create our string we're going to basically look and see whether the first seven characters are this so subject a bit of abuse but for all intents and purposes it's make sure we put the space in its it's fine for us so you won't put a space and just do that and if so then we will reference our caller ID variable and update its HTML [Applause] and then the same way that be pulled apart the string with the substring we also use it to display the good because we know we're getting a give it back we know what sort of particular length fairly comfortable that this is going to work it is quite it's a very crude method but we're going to upgrade to jason messaging later I didn't want to introduce that just yet though so this should be okay fun so the only other thing we them on the do is every time we get our connection Bible tell me to get a message sent back then we want to just check to see whether that's a if it's a connection message so up here on our own message event we will just call that function that's one ID and what we want to pass in is the event data and I'll save that so let's read this is still running so if we refresh our client what we should see is when we connect yep we get our message ID we've run our new method and it has in fact determined that yes let's start with corn ID so we've updated our messaging yeah not strictly necessary but just a nice simple function to round off this build section before we move on to the final you'll be pleased to hear fifth build section so we come on to the last part of the WebSocket building sure you'll be pleased to hear I'm sure I am pleased to hear it as well it's been quite long hopefully enlightening though and so in this last build phase we're going to be building the routing functionality of our application at the moment we just have clients yes they're now uniquely identified but they still can't send messages to each other so we're going to remedy that in the second and the other thing we're going to do is we're going to gracefully close out the WebSocket connection if we get that request from our client which we've not done yet and our server so that's all to come in this build section so first we'll move over to our web socket client and in here we're going to create a new support method that's going to basically construct our JSONP log message I'll quickly show you the article online so you can see what that will look like this is this is a very simple JSON it's key value pair object so we're going to have a from component to component and a message should be fairly self-explanatory in terms of our routing rules are very basic if we have a two-component pleasant then we're effectively going to send a message directly to that client we will check to see if we're still managing that connection on our server if not there mule arrow here if there's law valid to a component pleasant then we're just going to broadcast me st. every connected decline and that's basically about it so we're going to construct a function and our function a function and our client will call it something like John's RuPt Jason and you can I get Jason functionality of the box with JavaScript for many obvious reasons so we're going to just return a string and we're going to use the JSON object to stringify a number of components that are available to us on our client application so we're just going to take elements from our UI and build it into a string that is adhere to jason the jason standard so the first component is going to be a from component and the value of that is going to be our corn ID and our HTML but if you remember the coin ID is comprised of the world corn ID plus the goods you want to strip that out using the substring method again we're going to start at position eight and we're going to go all the way to the end of that particular strings or corn ID and at HTML length and get us to the end of the string so that's not two component sorry it's our from component when I'm doing or to a component that's simply going to be the value of recipients and then finally a message component is going to be the value of send message very good okay and then all we want to do is in here in our send button message he'll be constructed but he'll be just passed in the value of saying message instead of doing that we want to construct adjacent people instead simple as that I saw we need to division to change that and so the data that's now being passed or what is our JSON string so we can see that at work if we go back to our one of our clients and refresh it now so yeah let's just test that let's connect them cool and we'll take a message we'll just do anything recipient ID to click send yep there we go there's our Jason and the message they are a frog should be equal to our corn ID looks like it is or to is just this garbled nonsense and the message is also that all looks like it's what can correctly if you go what US server it received it's just a string as far as its concerned at this point of thing so what we named no but to do is pop over to our server and give with that message right so back over in our server classes just make sure that's stopped okay we are going to add our routing functionality to our server so in order to do that we need to add a coupler and you're using directives the first one is having Jason capability and we get that through the Newton soft Jason theme space and the other one is using system link I can't know what link stands for language accountant but it's like a query language where you can use to do queries on objects and stuff so it's very powerful and we will be making use of that in a bit so yes well in our WebSocket server middleware classify hadn't already mentioned that and having added those two using directives we want to add a new support method I guess you'd call it we're going to call it public async task load Jason message async along with the passing as a adjacent string called message so remembering back to the floor diagram we had on our routing rules the first thing you want to check to see is if the two component of our message string is about that good and if it isn't then we're just going to broadcast so let's start to code that huh before we can do that though what we need to do is take our message string and deserialize it and turn it in turn object so that's all the serialization means we're gonna get a serialized on a string jason string over the network from our website via our web socket i'm going to take that and turn it back into an object so newton soft jason allows us to do that so first things first we'll create a an object holder jason call anything you're right we'll call it will be and then we use adjacent convert deserialize object method to DC Eli's or string it's going to ask us what do we want or object we want to deserialize it to so we can provide a concrete object specification to if we want or we can just say you then you decide and not that's what we're going to do so if we want that approach then we just say dynamic and the deserialize or decides what the object is at runtime and what we wanted to see the eyes are message straight what this does mean though is the road will be object this can a loosely coupled so we don't really know what the attributes on our until Valentine which can cause some problems but it should be in terms of proving a concept it's fighting for our purposes so the first thing wonder then do is see if the to component as a valid good and you can do that number of ways you could look at you use regular expressions and that kind of thing basically than that I just decided to use the good tripods method which basically takes a guru that tries to parse it and if it's successful that passes out that good so I'll pass on rote or B now this is where we're not getting any intellisense drop them to tell us the attributes available because we simply don't know so we're just going to put it and we can you can use it as if it was the off but it may there was an error at one thing to string and then we pass out another good that's just the have a not going to do anything with that it's just the requirement of the method signature so if that does pass then we've got a valid good and r2 component and we'll do a targeted message otherwise we'll do a broadcast so let's deal with that first so we'll do a quick console.writeline something to motivate them pass them into the look right line and we'll just see vodcast and then if it is a podcast message what we want to do is we want to cycle Road and all the open connections in our manager and just say my message to every one of them so we'll do the for each look to clear our template got variable call it anything salt and in our manager and we'll have to call the get all sockets method to the tunnel our dictionary lists to the tunnel dictionary and then for each one we're going to check to see if the sock is open so f sock value state gives the equivalent to where'd Salk it stay open pieces that we don't want to send something to if it's not open then we're going to use the sendee sync method again so the synchronous methods we use away or reference it by going through the sock currents or object we have to use this value object to get to it and then we called the same desync saying these sync method so you should be familiar with us now so I'll just type it in as you've seen this before so it should be relatively familiar to you know if you want more information on the Sandy sync method probably best just to look at the documentation in short but we're just singing about our message string or the message component of our string and we will dominate those client hasn't changed but I'll just refresh anything let's bring up our other client as well and all these fresh so let's connect and we go do it to connect and we get a good let's just go hey now we've not called off we've not called our rotating method from within our function so before we do that before we can test that we actually need to call this and so we we want to call it from is back up here if we receive a message so if you remember we when we receive out a valid message we come into this call up well we've received it from a received message method and they may be entered into this action delegate stuff so we want to just add in after we've accepted though I have to be received a type of message to text and we should be able just to pass through this year that should work okay so let's try that again now let's save that and if you've backed our client which shouldn't actually it's just beef we reload them connecting again connecting again and we won't put a message in but no recipient ID so it should trigger the broadcast there we go so you can see here that it has decided that it was a broadcast and it has sent it to almost all clients including the sending Cline so that's all working which is good so let's just cancel that from the snow so I mean I have to go back to the targeted part of our router so we'll just write out to our console that's targeted well then declare WebSocket an individual WebSocket object and we want to retrieve back the WebSocket that we're getting the message on so we go to our manager get all sockets and this is where we use link to select a specific WebSocket assuming the socket isn't null we'll check to see whether it's open or not it's not open we'll just deal with that case first or just to see our disappear so we're not managing that connection but assuming that it is all key actually this should be here see that kill the silver and we'll want it again just refresh these connecting again and what we'll do is we will copy the connection ID from this client here put it in our recipient ID and type a message doesn't matter up spelt it and correctly and you can see here we have a targeted message and we only receive the inbound targeted message from this client need to get the open message on our send in client but you don't get the broadcast message so that's our routing functionality completed okay the last thing we need to do in this section before we move on to the signal our is make sure that we close our WebSocket connection gracefully upon receiving that for our clients so if we move over to our cord we aren't really doing anything in this class here so we call the receive message method and then if we received a text message back on it we do our we perform our routing functionality but we can also receive a Clause message in at the moment we're not really doing anything with that and again if you've noticed friend stop the server from running you even it will often see a lot of complaining and error messages being thrown around because we've not really closed down our web sockets cleanly prior to the application closing and this adings recording here to close those soccers gracefully will go some way to remedying that but that the license actually closing the socket from the climb if you choose just to kill the server application then I'm not dealing with closing off the sockets gracefully when that and that's probably something you would want to consider doing was not something you probably would want to consider doing is something you absolutely would have to do if you were building this in a production type environment but for now we're going to add in some cord the ball closed off a sock it's gracefully if we request that from the client and then we're going to draw a line under our web socket app I think it's in a sufficiently decent stately understand what WebSockets are and just the work that you need to do to get them up and running so back over in our cord and we're going to add some amendments I will just kill this first and again you may see that complaining messaging popping up at some point here we go this complaining which is what you would expect so the first thing we want to do and if we receive a Clause message is just to get the ID of the WebSocket that same as that Clause message so you do it in the following way create a string called ID and then using a manager object manager class who they see as an object really and get all sockets and then using link it's not sin to go foster default some things I find entail the Saints in chord yes chord doesn't work quite as I would expect it to the biblical basis usually pretty good so s goes to s value and that equals the websocket that we've received our message on then we want to bring back the key which is our corn ID in this instance and sort of popping that into our string ID that's quite annoying okay gonna get rid of it no okay what what I'm gonna do is we're then going to try and remove that WebSocket connection from our manager so it's no longer being managed before we close off so we'll call the try remove method and into people provide our ID which is effectively our key and out of that we are going to be supplying a WebSocket and I call it something like salt so that's what the try remove method on our dictionary does it will take an ID fine if it finds it then it will pass out the WebSocket in this instance that we can work with and clause so we'll then I just want to get rid of this message it's really annoying okay so we'll then await on our past Oh sock object and we will close the connection and that should be the method completed okay so we'll save that and what we should now see we thought let's build it first minute [Applause] my clients again haven't changed but really fresh well we load it and we'll connect and again if we click call socket we get a different reason cord the clean reason cord of 1000 and we should see something I'm assuming on the silver as well yes we received well we're just printing out we received the close message and we only had one socket connection there I believe so if we kill the application it shouldn't complain from this point forward so that brings us to the end of our WebSocket build you can see that on the JavaScript side of things that rail at relatively straightforward although I don't like JavaScript it's not that complicated on the dotnet side of things law you can see that it's a lot more complex now we did some additional steps just to tidy the cord up that we that we didn't really need to do but I think it was still worthwhile doing and the other thing to point out by no means is what by no means what we have written here is it suitable for any kind of production eyes application usage there's still a lot that we need to do they are to tidy up and make it robust enough that it would be something you would actually want to use but hopefully it gave you enough insight into how you can start to think about using web sockets and dotnet and we now move on to the signal our discussion and we build that app don't worry it's a lot quicker much much much quicker than the WebSocket build all right so we're going to start with our signal our build and before we do start with the cording is going to pop back over to the blog article and show you the architecture of an application though it looks very similar to the WebSocket application on the Left we have the HTML and JavaScript client the only difference is that we no need to include a external signal RGS of JavaScript library and then over on our server application on dotnet core application we only have one class that we need to create and that's each at hub class based on or inheriting from the hub class from signal Arnold talked a bit about that in a minute other than that it's basically doing the same kind of thing it's requesting an upgrade and to a WebSocket connection and then establishing a WebSocket connection so that's our very simple architecture and looks very familiar let's though and move on to the cording so let's just move that off to the side for the moment or out of it again and let's open vs cord once again and I'll change into my F Drive to start from a nice clean slate okay so as usual we want to do a dotnet you we want to build the web template application we'll give it a name signal or capitalized the are however they need to cool so yeah but didn't the starting with the server application first and then we'll do the client application okay so let's add let's open that fallen over to F Drive singing los up cool okay so we've got the usual standard web template project before program start up classes just say yes to that and now the first thing we want to do referencing back to the architecture diagram is to create this hump class now hubs are a central concept in signal are and they're really essentially responsible for handling the connections and also managing the messaging so they basically replace the custom classes that we wrote in our previous WebSocket application so we're going to create a hub class now that's the only thing we need to really create to stand up our signal our application so as purser on Microsoft guidelines you want to create a folder called the hubs I guess it just keeps it nicely organized and then we're going to create a file within that we're going to call it chat hub I can spell it correctly that hub see yes make sure it's a JavaScript a JavaScript a c-sharp file see I knew that would happen I knew I would get confused if I was doing two programming languages and the one in the one video I'm not that intelligent okay so we've got our entity class so let's next get calling on that so first our includes so we're going to do a few using statements system shouldn't come as any surprise using Microsoft if you know cool signal are and signal signal are is included in the mean asp.net core package we're going to use system threading tasks and then finally we're going to use Newton soft Jason as we did before to deserialize or Jason messaging and again used in soft Jason at the moment as of dotnet quarter point is included with that I have read somewhere I think with Dominic what three they might be swapping that is the default Jason package but I'm not I'm not sure about that so our namespace and I should be the same basically as our project Sigma soma and then class chat but make sure you spell that correctly and that inherits from hub okay so basically inherits from hub and we're going to actually override a couple of hub events connection and who's doing the connection unconnected you're not doing it connected on connect so we can send back the connection ID when we connect okay cool you don't need that constructor or anything like that so let's do that first let's override the on connect on connected event and it's an asynchronous method effectively so we pass back a task as you'll know familiar with and yeah let those two look console.writeline just so we can see it's a connected we can wait out to and actually saw one of the great things with signal are is that previously we had to create our own management class that the generate unique Goods and connection IDs with signal are that cannot comes out the box and the way we reference the connection ID for any connection is to reference this context object yeah the hub caller context and then simply within that there's something called connection ID that's the connection ID of our connection how simple as that okay so when we connect it will write out that connection ID to the console and then all we need to do on the connected event is saying that connection ID back to our client and all we do to do that is we references clients objects as a collection of clients I guess the client that we want to send to and we want to send to the client with the given connection ID so clients client what client do we want we want the client with this connection ID so it's kind of all's almost self referential and then the method we want to use the same async and then the method name that's going to receive this event on the client side we can call this anything we want but I'm going to call it receive caught fading so what this means is this is actually going to be a method or function over an hour signal our JavaScript client that will have to write and it will receive this event invocation and do something with it so you'll see that when we come on to doing our and we can want to doing our client application and then the next thing we want to send over is actual our context on a connection ID we go so just to reiterate when we connect will write the so type console so we can see it's rating and then we're going to reference any connected clients with this connection ID law should only be one of course and then we're calling the send async method to call this function over in our signal our client and and then just so we're adhering to the overridden event or method you're just going to the time I can spell it correctly the base I'm connected async and actually get out of all that hours so a we will just get a console up we'll do a build it all build okay right so let's move on to our send message method and this is the method that's going to get called by our signal our client to send messages to other clients so it's kind of like our routing it's kinda like a routing method in our WebSocket application so public async passes back a task send message es spiking key and we'll pass in a JSON string called message exactly the same JSON string that we passed in with our other application so that's not going to change cool now the first thing we want to do is DC lies our JSON string and make make it objectify it deserialize and we'll put it in an object called wrote or be jason convert the CL eyes object what type of object again we'll use dynamic again you could place in there a concrete class that metals your jason you'd expect in JSON payload that will just use dynamic for now and what are we deserializing that will Dec aligning our message cool now what we'll do just to just just to keep the verbose console output going we'll do a console.writeline and you'll just write out and got a message received message received on and we will use the context client ID one more time connection ID shortened to caller ID and I've got a plus in there okay so that's just going to give us some output on our console itself or console now the other thing I'm going to do and maybe I'll put it up here actually is I'm going to create a a concrete string called two that a good name for it mm-maybe it to the client yeah that's better and what I'm going to do is what you're going to use the route will be to component and actually place it into that concrete variable now the reason I'm doing that is because I've discovered when we come later on to call this method and place in the connection idea of the of the recipient using this construct I believe because it's dynamically taped it actually arrows I for some reason I guess because it's dynamically taped so what I've found is if I actually pause this object and pause this attribute of that object and put it into a concrete variable and then use that concrete variable and here it all works fine so that's why I'm doing that I didn't investigate it much more than that but that's why I'm doing that so what I'm just going to determine whether we want to send to one client or whether we want to sit over there we want to broadcast no just just for quickness and simplicity because this is becoming quite a quite a long video I'm just going to check to see whether this two client string is empty or not so equals string ante so if that's empty I'm not pausing to see if it's a correct good or anything it was just empty that we're just going to do a broadcast and the way we do that is a wait and we call clients again very similar to what we did up here to spell it correctly first two clients and instead of targeting a specific client we target all clients and therefore we don't need to pass in a connection ID we simply call send async and then we can we specify the method on a client that we want to call the seed message and we'll create this method of this function over the JavaScript client in the next section and what do we want to pass over we're just going to pass over the whole payload to all clients so that's our broadcast message so that is if this two string is empty otherwise we're going to basically copy this one we're gonna call people Type O but basically replicate that in method call so again will await clients client now this is where I'm seeing I had an issue if I I was using this and it was not liking it see it was a null object I believe so if we use this it should work fine an M you just do same-day sync what method to be sending or sending it to the same method is this one here I won't be sending or sending message it's as simple as that now we could put in some console late statements which I actually did when I was developing this you can as well just to see what's happening but I think it's fairly straightforward so our hop class we have two methods we've got this overrides method the bases are connected event where we send back the con ID to the client and the Salah message the seller method which is our send message method we our clients call that method to send messages to other clients that's all done okay and so we've only got a couple of little bits of code to put in our startup class and I'm done with the server built so let's move over to our startop class and again actually before we do that let's just do it build just to make sure the stuff we just did is is okay it looked okay now just just out of interest my F drives actually on an external hard disk so that's why it's taking a bit longer to compile I'm gonna guess so yes we're back over and actually you didn't save it so let's save it I always do that let's build it again and there yeah it's fine cool so back over and I start class again this is our new our new project so I'm just going to delete this just to keep the chord clean get rid of all this and also get it there so I'm not saying this stuff isn't important but just just to keep it nice and simple and you can see exactly what's going on then I like to just clean up so so you're quite familiar with both of these methods no configure services is really set up any services that we want to use through the pendency injection and I'll configure method as basically where we set up the request delegates let me cut our request plate plane now the beauty of signal are is we don't have to write any of this extra stuff herself it just comes out the box with signal are so the first service we want to add is add corrals no cause is cross-origin resource sharing what is that we'll come on to that in a bit so we're gonna add cause services to to be available for use float the application and then the other service can intimately guess what we're going to add we're going to add signal are ok again adds our signal are services available within our application and that's it that's our configure services method done and dusted so we're moving on to our request pipeline though though the first thing we're going to add to our pipeline is this cross-origin resource sharing saw app use cores and then we're going to use a builder to build up some attributes that we want to use as part of a cause now it's probably a good point to actually go over what is cause cross-origin resource sharing create a simple concept really it's basically we will have our server running in its own domain in this case it will be localhost colon port 5000 and as with our WebSocket application our client is going to be running in its own domain which is basically a well opening as a file so as far as our server is concerned running and localhost that's a different domain if there were both running in localhost you wouldn't have an issue but because of running in different domains that gives us a problem and generally by well as a security measure you do not want applications from different domains just being able to talk to each other at all and that's where corals coming across origins or shedding it's basically a method that allows you to admit certain domains to talk to other of the means and that's what we're doing here now you probably have a question how did our WebSocket application work without doing any of this stuff I will come on to that a bit but for now we have to use it the signal are and we can figure it in this way so the main thing you need to configure is for origins do you want yourself to allow in so our servers running is localhost for origins do we want to admit to connect so that could be the main URL or something of that nature now you do that by specifying this with origins tag no and here you were typically for HTTP the name of the domain because we're running as a file it took me a little while to find out what I should actually put in here and it turns out you simply put a string called null because when you look at the headers the request headers from our client which we can't do quite quite yet because I've not written it but when we do and they found remember I'll show you the head on the request headers with the origin value and the origin value is null I did try null it didn't like that so it does like No okay so basically you're saying if you see any requests from an origin of null you can admit that through know what the warning those request headers that specify the origin can be hacked or can be edited so do not just rely on this to say that application is authorized to use your service you probably would want to add another layer of authentication on top of that but for now this is what we'll use and we have to use it because we don't use this if we do it admit it then it just it won't work the other thing I'm just going to basically open the floodgate so you can see you get all these other options here so I'm going to allow any header I'm going to skip a bit annoying I'm going to allow any method and finally I'm going to allow any credential sought what effectively done there's I've just essentially opened up the entire floodgates which is not advisable but just to get this working that's what I've done and the main thing really is we're admitting this origin of the null okay so that allows our client basically to use our cell phone cool so that's that request delegate set up and then the last thing we need to do and now then I still have an application is done would you believe be do app use signal arm and in signal are we create something called I guess you'd call it an endpoint or a wrote point we're going to call it an endpoint and using a lambda expression that goes to the brackets in points actually let's put a little eyes this because you may have more than one and we're going to map our hub okay what hover we're going to map we're going to map a chat hub in here and then what we can do also in a signal arm you could actually do this in WebSockets as well I didn't choose to do that we can actually provide like you're looking you are a specified URL on top of our base in this instance localhost URL so this would mean you could have multiple hubs running at a different address so you could think of maybe if you have different channels or different teams or even different organizations it all have a different URL and that's what we're specifying here it's all call it chat hub cool so that's basically it on semicolon to put in so again just to go back with what we've done we've added our services that we require or me I we require cross-origin resource sharing we've set up our request delegate to be one of the first things we do in the request pipeline and that's basically just admitting anything with a null origin in and then they were setting up our end point which is effectively our chat hub so quite straightforward very readable very simple and that's basically our server app completely so just before we move on to our client build and while I remember I did say how did our WebSocket application work without using cores which is a very valid question and I asked that myself I'm referring to the Microsoft documentation and actually make sense based on what we know about WebSockets that essentially they are very basic they're very simple very powerful but simple they don't provide a lot of anything else out the box like management or security so basically out the box if you're using pure WebSockets they don't really challenge you for any kind of cross origin violations they just work okay so that's why why our WebSocket application just what so the signal are obviously guys would all that framework they built in this extra security check or validation that you must add cause to a signal our application and order for it to work no with WebSockets you can actually still add cores to your request pipeline and that's all good but you don't have to okay so that's fine our WebSocket application just what and it's possibly depending on your viewpoint another reason or a reason not another reason a reason why signal arc may be preferable to WebSockets but again depends upon your perspective a sports okay so let's let's move on with our client don't know okay so we're going to move on to our signal art chat client no because we've already created a WebSocket JavaScript client there's almost of a lot of the cord not most but a lot of the cord is basically exactly the same the HTML is pretty much exactly the same and large sections of the JavaScript is exactly the same so rather than type all that again which I'm sure you don't want to watch and I certainly don't want to do I'm gonna use the Seaboard and I'm gonna cut or copy and paste that cord into our new signal art project now what I've done is I've actually created like a template of the cord of already used I've taken out some of the bits we don't need from the WebSocket client and any new cord I will be typing in so you're not going to miss anything any new novel stuff related to signal are I'm going to type in anything you've seen before I'm just going to copy and paste them okay so hopefully you're okay with that so we all leave our server project open let's just do a dotnet run just to make sure it's running okay looks like it's running okay we'll leave that running actually now what we want to do is we want to create our signal our client project all I'm going to do is basically create a folder and I'm just going to call it signal our client and then we'll just have a new window and I don't like how this goes off the top of the screen it's cuz I've got my screen magnified so it looks a bit easy it's easier for you guys to read on smaller devices and we'll simply open that folder sitting our client make sure we open the right one and we've got an empty it's not really a project but an empty folder and allowed and you fail and we'll call it single or HTML and this is something I don't really want to do but I'm going to do it let's paste the core then actually it's the right thing to do because I'm sure you don't want to see me tape all this stuff in so all the HTML you will have seen before and it is exactly the same does not change the only thing we're going to change is the word WebSocket to signal our that's all so nothing to do complex just so we don't think now our talk to spell that one I actually think I might be slightly dyslexic Sanwa okay and I am at mumbles I can't I find it very difficult to read out long numbers that if you get like a phone number I need it separated the spaces all of my them I'm totally lost so other than that the HTML stays exactly the same this section of JavaScript will be basically creates JavaScript objects for my HTML elements stays exactly the same our first change comes here and instead of using raw WebSockets we're going to be using HTTP with Sigma ultimately it will use WebSockets in the backend but we connect and using HTTP and then if you remember when we created our endpoint in our server application here we mapped our chat hub to an endpoint we have to put this in we should copy that in at the end of our URL slowly connect into a chat hub okay so fairly straightforward changes I'll just go through what we've already got here just so you're comfortable we've got our connect button on clicked event we've just got updating the status and add addition to the comms log we've got a close button on click event that's good nothing in it at the moment seemed for a send button on quick event there's nothing in it but they were sorry was this wasn't it on today tap that and they've got our entry to our comms log this will arrow so let's just take that oh just know based on our HTML escape function that means exactly the same that does not change this function will be we're looking for this coin ID and we're kind of pulling that apart with the string that we're getting back it's a very ugly function and in fact we don't need it anymore so let's take that oh it's gone and I'll construct JSON payloads which is basically string a fiying the message that we want to do that stays exactly the same so that stays as is and then a final function that you've seen before is our up the state function this does change slightly this is the WebSocket code that we've got here I've not changed it but we will go through minute and change make the necessary changes to the switch statement saw the bow reflecting UI changes accordingly okay so before we touch any chord and our signal our client application one of the things that you'll remember from the architecture diagram was that we rely upon a library file or an external javascript file called signal RGS so we need to include that and drab that for our project now the tool that you use to do that something called Libman stands for lively manager fairly self-explanatory it's a bit of a new get it just allows you to get client-side libraries and hand them to your project so first thing you want to do is check that you have it installed so back over in our project just make sure it in the right directory yeah but in our client actually if you just take blood man - - version if you have it installed together there's a number coming back if you don't have it installed it'll complete more such application or program file or something like that so to install that I'm gonna break all my rules again and I'm going to actually show you the string that you would type in this is also on the blog and I'll flash up in larger text on the screen here when I come to editing the video but you'll type in dotnet till install - g microsoft word dot lively manage or CLI and that will install it for you i don't need to do that cuz i already have it so it's good bit of that so the next thing you need to do is then tell that man i want to get the signal our library files so but man I really should probably cut and paste this in as well but I'll speed up the text speed up the taping so install this final signal signal our signal our GS into if I a file called folder sorry Cortland for size signal our four slash dist 4 stars blows applause - you know it's cool being run that you can see something's happening up here there you go let me say installed live - asp.net Sigma 2 Lib Sigma R so in here you should have yeah yeah Sigma distribution browser Sigma og yes and it's just a JavaScript rather large drives javascript file that we will want to include so let's let's do that now let's include it in our in our application so to include it be something for another script script tag and it's quite nice it will correct you if you're a terrible typo like I am and what I really love about Visual Studio quarters will actually provide you with this kind of almost like an Taylor sense drop-down folder structure how beautiful is that isn't that isn't that wonderful that's just our beautiful and it completes it for you my goodness that's rather magnificent so what we might do just to test it is go to our client application for but I mean might just open this in Nice often in Firefox now what again what I'd like to do usually is bring up the console just to make sure those no errors are warning and it looks pretty good we just do a refresh looks pretty good if you do a view source let me click on this it takes us the apt also but anything's set up correctly it's all looking rather good let's just make this a bit smaller life is good okay so we've included a we've included our signal RGS file into our application now it's actually thing to start calling up an application so the first thing we really want to do with with our signal our client is create our hub so in the WebSocket client that we've done previously we had a WebSocket you don't use that here in signal our we use what it's called the hop connection connection to the hub so that's the first thing we want to do in order to start using it so available call it anything you like let's call it hump connection and you build a hub connection using something called a hub connection build up which is something that's available through a signal are so we access that through signal our and then hub connection build up we pass in a a URL lure surprises what URL we're going to pass in yeah we're going to pass in this so it's just passing a value here and then we just chain that with build so fairly straightforward we have this hub connection though there be you're creating or building using our connection URL value so we want to obviously open that connection now in the place to do that is and our connect button click events or you'll see this stuff here that's familiar from our previous application have just got an attempting to connect well then I'm going to do something which is what we're going to do with our hub connection object so the way you connect to a hub is to use the hub connection object and then call start method on it if it starts then function and basically do something so all we're really going to do upon connection is update our state and also write out our comms loud so let's just copy this copy it cut it and paste it in and yeah see that we have a opendoc connection fairly straightforward now the one thing that's not going to work is I'm the one thing I did mention previously as our up the state method will need a bit of updating before that will work so let's let's jump down and do that now so here we are update state now the only thing that we really need to change on it's a few things we need to change this stuff here these sub functions of the stable and enable all remain exactly the same the first thing you can see probably needs changing is for ref leasing or old web socket socket instead of that we're going to type in if you don't have a hub connection then but just the say bling ever thing and then likewise down here we don't have a socket ready state will use hub up connection state now the other thing that we'll just mention here we've included our signal our lively here apologies that's my phone going we've included our signal our library here and I've tried a few other ways to kind of almost reference and include the signal our library in this client files so that we get the intellisense drop down I've tried everything and I can't get it to work so if you find how you can get out if you can get that working let me know and I'd be very much grateful but one of the manifestations of that is I can't really on a can't figure out how to look at the hub connection state and limitations and use those so understand unfortunately we're gonna have to use magical strings hard coded strings which I absolutely hate and the only way I could get that was actually they're going into the signal our file and looking in the chord there to get those connection states so the first connection state matches under by I change there was our previous web socket closed state so instead of doing a case on that it's simply disconnected there's no such state called closing in signal and we'll take that out there isn't a connecting state but they are well actually sorry that is a connecting state but we have to reckon sit through a magic string connecting and then that isn't really an open state there is what they call a connected state so let's change this to connected and they don't have this either so let's take that out that's just two more for no so that for me is a little bit of our what can progress that I would like to use proper enumeration so you and get the intellisense working for the signal our library I can't seem to get it working not sure why at this stage otherwise it's fine it shouldn't impact our cord just bear that in mind anyway I'll upstate update state method that should should snow that should still be should snow should now be working I've been talking way too long so we can test our on click event because we're starting our hub and assuming it starts and we should get our updated state and something on our comms log so I believe our servers running yeah it's running so if we go back over to our client that's refresh it let's connect so we get connected state which is cool amigo our connection opened which is cool so with that all working let's move on to the rest of the functions that we have to change so let's move on to our clause button that would probably make most sense so in a very similar way as we did with our WebSocket but just going to check to see if we've actually got the hub connection object previously we were checking to see whether we had a WebSocket object and do we have one or do we not have one should I say here or and at the hub connection state is not equivalent to connected and we're just going to basically a bunch of needles Bacchus we're just going to lay out and say something along the lines of pub not connected okay cool assuming have a vault actually most do some back here soon okay cool so assuming is good then is we called our hub connection start method up here we're going to call any guesses what we're going to call all our connection stop method and yeah well yeah so we're calling we're requesting to stop the connections or that's assuming that request is successful the connection may not be the connection may not be stopped with merely request that it's been stopped so what we'll put in here is well just do a console debug and I'll just say requested stop on hub and so what I mean by that is we've just said listen we want the connection to stop at me not have stopped it merely requested it so what we're going to do to medal that is we're going to hook into the hub connection I can spell it correctly on Clause event [Applause] and we can if we need to access some event parameters we're not going to actually use them but it's they used to have them and all we're going to do is update our state to just check to see whether yes indeed the connection was stopped I what I'm gonna do is I'm going to copy this paste it in here and making sure that I change this from connecting because I could get very very confusing to something like connection disconnect well maybe we should use the language connection stop okay so let's test that I think we have other thing that we need to test connecting and stopping starting and stopping so let's go over here refresh it if you connect we've got our connection opened cool let me close it and we'll have not connected okay I think there's maybe an error and my cord there so we're getting the right messaging and a comms log and our correct state reflected but we're getting the a layout popping up I think I must have made a mistake somewhere in here doesn't equal connected yeah weird let's try that again shall we just to prove that this is live coding and a lot or anything and I did all the state edit a lot of stuff you don't see but I do try too late to solve things in real time that's better okay so we can connect connection opened connected state closed as the socket connections to stop okay very good okay so that's our connection disconnection all sorted out what we're going to do before we want to come on to our other events we are going to now introduce one of the methods or one of the functions that you referenced from our hop so if we go back to haben you remember when we get a connection event on connected a sync event and our hub we say we've got a connection established and we have this connection ID what we then do is we then call this method receive caller ID on our client and pass back or clone ID now at the moment we don't have this method and our signal our client app we're going to add that now so when we connect this should trigger and call that method back on a signal our client update our UI with the connection ID so why do we do that now why not what else are we going to do okay I'm gonna have a cup of tea after I finished the section that's what I'm going to do but for now let's let's introduce that function so the way that you do that in signal eyelet is actually very cool you'll take hub connection obviously and then on for sort of generic event handler so I call it and then we take panitch that it's make sure we type in the right name because it is case sensitive received come on ID yeah okay so hop connection on the calling of this method which we are now about to define function expecting a coin ID to be passed them to that function all we're going to do is update our UI element con ID and our HTML and we're going to set it to con ID which is the string that's already displayed and by default the see na and will display the clone ID making sure you select the right one the con ID you know cool okay know just before I go on some of the documentation I read it suggested that you can actually access the con connection ID just from within the JavaScript you don't actually need to do what I've done here and trigger a method from the hub to pass the caller ID back doing about a research and I've still be a bit confused by that I couldn't actually get that working referencing the client ID from within in JavaScript but then I also came across post by one of the contributors to signal arm he said that they deliberately have removed the ability to access the clone ID from within the JavaScript because they don't want people doing that what do you want people to do is kind of cross reference the Carnegie connection ID with the users login ID and use that and stay there's a method of identification we're just kind of fin enough and you know that's kind of what I suggested we do with our WebSockets as well you don't really want to be working with raw corn IDs it's not very user friendly it doesn't look very nice but for the purposes of this demonstration I'm quite happy to use the clone ID and so I'm kind of bypassing I believe what the signal our team are suggesting you don't do I'm just making you aware of that but for all intents and purposes we're just trying to route messages to endpoints and I'm using the clone ID to do that I didn't want to build in this association layer between your user ID and the client ID so that's my view on it if you've got a different view please drop me a line to a message in the comments below or drop me a line on the blog or whatever I'd be interested in your views on that so that's why we're doing this we're actually kind of bypassing the signal our team's wishes so then all I want to do is just update our coms log and you will excuse me I'm just going to paste that code in so coms log connection ID received from the hub this is very basic HTML it's just going to be very boring if you watch me type that and I don't want to bore you so let's save that and then once it's saved we'll move back over to a client refresh client and what we should get when we connect is we should get the client ID pass back and DB do so our connection has opened we've got a connection ID received from the hub we have the connection ID they are all very goods but on the final phone long we're almost at the end of coding up our signal our client so all we've really got left to do we've got to or methods that we need to complete though the other one will do quite quickly is kind of the sibling of this one here where we have our received client ID event or passing by the corn ID and if you just pop back over to hub we did have one more which was receive message okay so basically on then location of that method on the client we're just going to basically display the the payload the JSON payload and our comms log it's that simple it's not really a fancy but it's just proving that we can receive that message so once again hub connection on and let say we pass that method in let's just go back there copy that in on receive message and in a very similar way I'm just going to define a function to handle it passing the message now all we're really going to do is just print that message out onto the screens nothing really more fancy than that so again it's just very basic HTML updating our comms log so rather than we're taping in because you've seen it before I'm just going to paste that in so comms log and an HTML blah blah blah for escaping the message no the only problem is with having done that that's cool but there is no way as yet to send messages for my client we've got a button or send message button but as yet we don't actually have anything it's not doing anything so that's the last piece of our puzzle if I can if I can find it so here's here's our send button event and we've got I already had this and here it's basically just showing you the message that's going out from our client to the cell bar so what we no need to do is basically when we click this button what we need to do back over on our cell but as we need to actually invoke this message to trigger rotating mechanism over to the other clients so let's do it and once we've done that do you know what we're done it's all we're going to do is very similar actually not similar identical to what we did in our WebSocket climb and basically construct a JSON payload and put it in a message object although it's basically a string and then here's here's the bit of novelty that you've been hanging out for on a hub connection we're going to call this invoke method in his face similar to how we it's basically the opposite of what's happening here so our hub invokes these messages whereas our client is going to invoke our send async method that makes sense it should basically just opposite ends at the same thing so my eyes are going across though let's paste that in there and I'll be saying all that is the message and to be honest with you it's that simple so by calling this invoke method on on our hub the base is going to trigger this message on our hub and our hub is then going to run through it's rotating logic and then fire off that message to either all clients or a targeted client it's really that really that simple and then all I'm going to do again is actually already there isn't it I don't need to copy and it's already there I was just going to say we need to update our comms log but that is already there so that's all we actually needed to do on our send event create our message in fact I should have left that in from last thing because it's identical and then all we do is call the invoke method on our hub save and with it's saved if we fire up our client let's try it just with one client to begin that's rather than getting overly complicated so let's close our socket let's refresh our client will connect in we've got this ID now if we just type in hello hello everyone it should broadcast out to every client on our connected to a hub we've only got one client connected to a hub but you can see here form the client to the server over singing this pay Lord and because of broadcasting we have seen a Hollywood received that same message back from the hub so it's kind of like your traditional air core tape scenario so what if we what if we if I can find amongst my millions of drives for the client is let's open up let's open up another one and that's taste that's test i broadcast again no you'd have to connect first and then send cool so again we get the double messaging here on our sending client but we get up and bond broadcast message from from the hub to this claim so again it's very similar to what you've already seen with the WebSocket stuff I'm probably not going to need to spit this one in here just to test that if you put a recipient I in the hearing go a little forum replying to you go get an inbound message from our client and we get on the debt no message from that other client so I can't believe it we've got to the end of the cording you'll be pleased to hear so I've done about you I'm going to take a quick break but without a cup of tea and then I'm going to come back and I'm going to wrap up for you well that was a epic shoo sure you will agree a over the others edited down in fact to over three hours that was my intention it's just the way things panned out so which is better coming back to the whole point of the video of which is better WebSockets or signal are well I'm sure as you probably realize it was a stupid question it's not a free up question and really the answer as well it depends of course it depends what I hope this video did give you though was enough information to make an informed decision about which one you would use in your projects and ultimately it boils down to do you want to build your own management layer or do you want to use someone else's that they've already built for you as in signal R or do you want to use pure web sockets for you're going to have to build your own stuff around the edges of it and that really is it that boils down to that question you're gonna have to build a management they are anyway which one do you want to use and it really depends on your situation for me personally I enjoy I enjoy using both of them I enjoyed learning about both of them it would depend on what project or what my situation was in terms of which one I would choose to use at this point in time I'm enjoying using WebSockets cuz its operating in that low level and I can I like building up my own management layer around it signal model is perfectly decent and I could totally see why somebody would choose to use that and in fact one of the things I didn't mention about single art is that if it can't use a WebSocket to establish a connection it will fall back to I think it's long pulling so it's very versatile really powerful actually and it can probably save you a lot of headaches and if you're using it for a real world application but again that's entirely up to you so anyway I'm going to leave it there for now I think I've been speaking more than enough and I will see you again next time but I hope you can join me for a much a much shorter than last lengthy video but until then thank you again and I'll see you next time
Info
Channel: Les Jackson
Views: 47,344
Rating: 4.9716311 out of 5
Keywords: dotnetplaybook, websockets, signalr, binarythistle, les jackson, .net, .net core, request delegate, async await, c#, step by step, tutorial, request pipeline, realtime, compare, compare websockets signalr, compare signalr websockets, difference websockets signalr, difference signalr websockets
Id: ycVgXe6v1VQ
Channel Id: undefined
Length: 206min 21sec (12381 seconds)
Published: Sun Jul 28 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.