WebSocket Tutorial with Spring Boot | Build One On One Chat Application

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today we're not just exploring we're diving into the heart of websockets as a quick recap websocket revolutionize communication on the web by establishing persistent full duplex Channel between clients and servers now if you've been following along in our previous video we unveil the magic of we circuits and even crafted a lively chat application where users could engage in group conversation in the shared chat room it was a blast but today brace yourselves for something even more exciting we're taking the concept of realtime communication to a more personal level picture this a one-on-one chat application that allows users to have private secure conversation and guess what we're not stopping there will be immortalizing the chats by persisting them in the DB dat database but before we jump into the code a quick shout out to those who want to deepen their understanding of websockets so if you missed the introduction in my previous video find the link in the description and watch it it's worth it I promise now if you're not part of our community yet hit that subscribe button join me on social media and join me on my journey of exploration and learning and of course coding I release new and exciting content every week and I wouldn't want you to miss out I'm alibu a season software engineer and I will be guiding you through today's exploration without further Ado let's embark on this coding Adventure we'll build a one-on-one chat application explore the intricacies of websockets and master the art of persisting data in mongodb are you ready let's get started in the previous tutorial about spring Boot and websockets we built together a chat application but it was a kind of little bit specific so we had everyone is publishing to the same queue and at the same time also everyone is subscribed to the same queue this means a message sent by Alex will be seen by Hunter and Maran 2o and the same for the other users so every time and each time a new user connects to the chat application all the users will be notified and they will see that a new person has joined and he will see all the messages coming from everyone which is fine and nice to have a public or a general chat application so now we want to build something a little bit more advanced and a little bit more personalized so what we want to build is to have a onetoone chat application so we will we will try to keep the same concept but we want to have a private chat so we want to have a private communication between for example Alex and Hunter or Hunter and Marian and so on and so forth so next let me explain to you how the diagram or how the queue and the communication between this private chat will be now let's understand how a one to one chat is going to look like so let's take for example example two users John and Maran and they will be talking to each other so the concept is John will be publishing a message to Marian's q and it will be named for example Maran slq messages and then from the other side or from the other users side Marian will be subscribed to her own or its own queue so Marian will be subscribed to a queue called Maran /q/ messages and so on so forth so now let's see when Marian will be sending a message to John so here we have Marian now on the left hand side so Maran will be publishing a message to johnq SL messages so Marian will be publishing message to John on his own que and then John should be subscribed to his own Que in order to receive messages immedi mediately so this is also like part of the how websockets works and for people who started watching the video from this point I would like to invite you to check the old or the previous video I published about websockets where I explained really good how websockets work all right so now this is how a onetoone publishing and subscribing to uh each other's event and to each other's messages is going to look like the next part I will explain to you how this is going to be like an overview of our application after understanding how a onetoone chat or communication works with message Brokers so now let's assume that we have a connected user at this present moment is Mr John and Mr John is subscribed to his own queue which is called john/ q/ messages and of course in one to1 chat application so everyone can talk with everyone so let's assume that Alex will be talking with John Hunter the same and Maran so Alex Hunter and Marian they will be publishing or pushing messages on John's q and John should be subscribed to his own que as explained before but now we need some information from Alex Hunter and Maran in order to know and understand who sent a message okay so we know already to whom this message was sent but we need to know the sender and then after that so this will be some information that we will provide later on and after that we want to persist the chat between each users in order just to have for the next time for example when the new when when the user logs out and logs in again he will find trace of all the messages so we will be persisting everything and for that and as explained before we will be using a nosql database and for this case and for this tutorial we will be using a mongod DB and for that if you want to learn a little bit more about mongodb I would like to invite you to check my website where you have a full course that will explain and help you understand DB all right so now let's continue so here we have John and after after receiving a message or after like sending any message to this John's queue this means that we will have or we need to persist this communication so for that we will have a chat room so a chat room it will be a document and then the service and so on so forth so we will have a chat room so the chat room will will look something like that so for example we will have two chat rooms one chat rooms for for example Hunter and John and then John and Hunter so we will give it the same chat IDs we will have Hunter John but we will have the sender ID and the recipient ID are reversed so for example the first time we will have the sender ID is John and the recipient ID is Hunter and then we will have the sender ID is Hunter and the recipient ID is John so we we will be creating a pair of chat rooms between two or between each couple of persons that will be talking together now let's take for example the Alex and John so the same way we will be creating a chat ID or a chat room and we will give it an ID Alex and John and the sender is John recipient is Alex and the sender ID from the other side is Alex and the recipient is John so then if every time we receive a message of course we need to keep trace or to save this message so for that we will need a document we will call it chat message and for that we will have the chat ID who like to whom this message uh or between whom this message was sent so we have for example the sender ID is Hunter so hunter sent a message to John and the content is hi there and we can also have a time stamp and then from the other side we can have for example a communication between Alex and John and it will be the chat ID Alex John the sender ID is Alex and the recipient ID is John so the the content also hello Jo John with a timestamp all right so this is a global overview how our application is going to look like so here as you can understand we will be having some documents and this one we will explain it in just few seconds all right so now let's move on and let me explain to you which documents we will need for our database perfect now let's see together how our document all like the links between or the relations between our different uh documents in our database will look like so for that we will first of all we will need a document where we need to persist our different users so for the user we will have a nickname full name and the status so the nickname should be unique and the full name like it's the full name of the connected user and a status whether if the user is connected or disconnected like whether it's online or offline so then we will have a chat room where we will have a chat ID center ID and a recipient ID so as you see here so a user can be at the same time the sender and the receiver so that's why here I just put it two lines or two connections with the chat room the same with the chat message we will have a sender and a receiver ID and then we will have the chat room so as you know like with no SQL databases we don't have this relationship ships but it's just a diagram to explain to you how things are going to be linked all together so this is a simple overview of our application so now the next step is start coding so let's start doing it so first of all let's start with creating a new spring boot project so as always just go to the spring initializer or use your preferred way of creating a spring boot project whether from the the IDE or from the web as I'm doing right now so here first I will be using a maven project Java language and let's use the latest stable version which is 315 at this time and then let's go ahead and create our group ID so I will call it com. alibu and then the artifact will be websocket so websocket right here and here I will just update the description with web socket and and this is will be our package name and we'll be using jar packaging and also Java 17 and now let's go ahead and add some dependencies so first we need our spring web and then we need websockets and then we need DB so here just type and here be careful you need to use the spring data mongodb not the reactive mongodb all right right and finally we need lombok just to reduce the boiler plate code and all we need to do now is to click on generate and then open our project in our preferred IDE so let's go move move ahead and do it so here we have our spring boot project and the first thing that we need to do we will be creating a Docker compos file where we will have our services that we will be using and in this case we will be using mongodb and Express in order to have our database and also like a tool to explore this database so here in the root folder I will create a new file and I will call it docker-compose do yaml and here just be careful the name should be Docker Das compose and here so we will be be having services and the first one we will call it mongod DB and and then the image will be from and then we will be we will need a container name so let's call it mongoor DB and after that we will need to map some ports so the first one or like will be working on 2707 over 2707 then we will need to map some volumes and here we will have volumes and for that we will be we will be use using a mid volume so it will be and then slash data so also if you are new to Docker I would like to invite you to check the video that I posted before on my YouTube will help you start with Docker all right so after the volume we need to specify some environment variables so the first one is called and then underscore init DB so do init a database and then root username so here we need just to give it to give a username and then equals and we call it alibu for this case and then the second one we will be using or we need a password so I will also just copy this one for a faster update and this one is called password so DB init uncore init dbor root _ password and then you need to specify the username and the pass password and that's it so now we are done with the mongodb service let's now create a Express so for the Express we will need an image which is called also Express and then let's give it a container name and let's call it mongoor express and after that here there is a property called restart and let's put it to always so like we want always to restart start our container and now let's map it to a port so the port let's use 881 over 881 for example so this is the 881 is the default port for Express so let's use it all right next we need to specify also some environment variables so here the first one is called Express andore config and then underscore mongod DB underscore admin username so admin username is one word so here let's call it also alibu and I will duplicate this one and here it will be also admin password so let's rename this one to password as you can see right here and the last one is also I will just copy and adjust so it's uh Express config mongodb and here we have server so our server server is our DB server all right so this is the server that we want to connect to and finally at the same level of services right here we need to create some volumes so here we just need to create a volume let's call it and then colum and just brackets so this is going to reference this one all right so again if you if you're new to Docker and docker compose I would like to invite you to watch the video and you will learn many things about Docker so now we have everything up and running so in order to start these two Services all you need to do is to open the terminal whether from your IDE or your laptop's terminal and just type the command docker-compose up and you can also use minus D for a detached mode but let's keep it this way and see see if everything is fine so for my case I already have container called mongodb so I will just go ahead and started from there all right so now let's move on and let's start creating our application all right now let's go ahead and configure the connection to our database so here all we need to do is to provide some properties and you know my style I would like to work with yaml representation you can also continue working with properties it's also fine and it depends on your personal preferences so first I will provide some information spring. dat and then mongod DB and then I need to provide the user name so as we made for the configuration the username is alibu so this is what we provided in here and the same for the password so then we have password same alibu and then we need to provide the host uh not additional hosts but just host so which is Local Host because like we are running our application locally and then we are running it on the board 2707 so it's 27 here and then we have a database so our data base that we want to use let's call it chat andro underscore app all right so this database we need to create it later on and then we need to provide the authentication database which is admin all right and then I want to run our application on the serverport 8088 all right so now we have our application configured and ready to connect to our database called chat app that we need to create later on so now we can can move on and start configuring our web socket now let's open our Java package right here and enter com. al. web socket let's create a new class let's call it web sucket config and I would like to place it under the package called config all right so it will be config do websocket config all right let's hit enter and here we have our configuration class so first of all in order to mark this one as a configuration class let's give it The annotation configuration and then we would like to enable the web socket message broker so let's use The annotation called enable web sucket message broker and then in this web sucket config class we want to implement an interface called Web socket message broker configur and as you can see this is the one that we are talking about so let's select this one and first let's have a look at this interface so I'm going to download the source and let's see what this interface is about so this interface defines method for configuring message handling with simple messaging protocol example stomp so this is what we will be using from websocket clients so here as you can see we have a bunch of default methods that's why when we implemented this interface we didn't get any error message telling that we need to implement the missing methods so because we have default implementations and as you can see it's all empty implementation all right so now let's continue with our configuration and we need to override two methods or three methods exactly so the first one there is a method called here so I will use Implement methods the shortcut and also every time I use a shortcut you will see a green popup right here telling you which shortcut I'm using so we have a message called configure message broker so configure message broker so it's the last one and it's the one having a parameter called message broker registry so let's click on this one and now let's delete this and start configuring our broker so first we have registry and then we want to enable the simple broker and then I want to use a prefix which I want to call it/ user so the destination of our broker will be/ user and then let's add another property so here I want to set the application destination prefixes and I want to call it slash app all right so so here I have an extra parentheses let me remove it and finally we need to add a registry do set user destination prefix and also I want it to be slash user so slash user and that's it now we have the configuration of our message broker so next we need to register our stomp end points so for that let's again Implement methods and we have a meth meod that we need to implement called register Stomp and points so for this one we need to have registry and then add end point so our endpoint will be /ws to say for example this is the path for our web socket and then dot with sockjs all right so now we have the second method already configured we need also to configure another one so the latest method that that we need to implement is how we want to convert our messages so we need to add a message converter and this will handle the conversion or like the serialization and deserialization of our messages so for that let's again override another method and it's called configure message converters so this one it comes with a list of message converters and then let's return turn false here and after that I will tell you or I will explain to you why we need this false later on so for that we will need an object of type default content type resolver and let's call it resolver equals new default content resolver and then so now we need to set some properties so here we have our resolver DOT set default M type so our default M type we want to use application SL Json so we have here a class called MIM type utils do application uncore Json all right so let's use this one also we can use import static so to make it shorter and more readable so here we need also to provide with what is the mapping or the converter that we want use and for that we can use the mapping Jackson to message converter so this one let's call it converter equals new mapping to Jackson message converter all right so then we need to tell our converter that we want to set an object mapper and here we can use an object of type object mapper and then we need to give it or tell it which resolver that we want to use so here we want to set the content type resolver which is our resolver we just configured and of course we need to add this converter to the list of the message converters that we have so do add and then we need to pass our converter that we just configured and then we return false and I will tell you later on why we need this fals all right now let's understand why we need to return fals here for this configure message converter so first I will hit control or command and then click on this me on this method so this will redirect us to the delegating web socket message broker configuration so this is the default configuration that spring will be using and here as you can see from the code so if the configure message converters so this is the method that we just implemented this one so if this one will return false this means that we don't want to use the register or we don't want to register the defaults all right so that's why we need to return fals here also I would like to invite to just play a little bit with this one with the return type you can return true in here and then check why or how this is going to work all right so now let's move on on and start implementing our application all right after configuring our websocket we need to start implementing our application so the first thing that we need to do is to create a user object so I will create a package called it user and then user class so this user I will need these annotations so first get her and set her from lombok and I want it to be a document since I want it to be persisted to my DB database and then I will have a private string nickname so let's call it nickname and then also I would like to have a private string full name and finally I want to have a status for so like to say if the user is online or offline and then we call it status so for this one you can we create an enumeration or you can use a string simply all right so for my case I want to create an inam and I want to call my the two status of the user whether the user is online or offline so here should be a comma and now we have the status and we have the user document and of course this nickname I want it to be an ID and here the ID should be from Spring frame framework. dat. annotation package all right so now we can close this one and now we can move on and create the user service and then the user controller for this user domain all right so now I will create another class and I will call it user service and in this user service first I need to make it service so I need the service annotation from Spring and of course I need required arcs Constructor and now I need to create three methods so the first one it will be a public void save user so this one is to save a user and I will require a user object all right then I would I would like to have another one so public void disconnect so this one is to disconnect a user and also I will ask for a user user object and then I need to disconnect my user and finally I would like to have a public list of users and I will call this one find connected users so this will return the connected users from my our from my application so here let's return null for the moment and we will Implement these methods one by one so here what we need to do we need to have our repository in order to be able to communicate and interact with our database so here let's inject private final let's call it user repository and let's call it repository as a short variable so for now we don't have a user repository class so let's go ahead and create interface in the same package websocket do user and here we need to extend and repository all right and this repository is of type user and then a string so the string is the type of our ID all right so now we have our repository ready to use so then let's start with the save user so here when we save a user because saving also means connecting and we will see how this is going to work later on you can also feel free to update adjust rename and like introduce other objects introduce dto representations requests and so on so forth this is just a tutorial to show you how things work and then I will leave you all the freedom to extend and to improve your code and application so here for the user I want to make sure that each time I want to persist a new user I want to make to set a status which is online okay and then all I need to do is reposition itory Dove my user all right so this is the save method then to disconnect a user all I need to do is the following so here I will create VAR and then I will say stored user or connected user equals repository. find by ID and then I will provide the user. get nickname which which is our identifier and then I will do or else I will just return null okay and next if my stored user is not null what I want to do is to say my stored user do set status and then offline and finally repository Dove my stored user so it's just updating the status for the user and of course we need to update the status only when we find our stored user all right and finally here what we want to do is simply to return repository do find all by status so for now we need to pass the status. online and we don't have yet this method so let's go ahead and create it so and then that's it all right so now we have our method we have our service ready to use let's move on and start implementing our controller after finishing the user service we need to create a controller for the service so let's create a class and call it user controller and for that we need first of all an annotation here controller just to mark it as a controller and of course we need the required ARX Constructor in order to inject our dependencies so here let's let's use private final our user service and let's call the variable service and here we need three methods all right so the first one is the save user or adding the user and then disconnecting the user and finally we need the method that will return the list of the users so here I will say public user and then I will add add the annotations and I will explain them one by one so here add user and for that we need our user object all right so then I need to call my service Dove and then I need to save this user and just return the user that we received okay so now let's start with the annotations first this will be a message mapping so I we so we want after the user is connected so like now we talk about the UI that I will also uh explain and implement it step by step so from the UI we will have a form where the user needs to type his nickname and full name and after that we need to notify all the users and send a message to our web socket okay so here we need to have a message mapping so that's why we will be using slash user do add user user to add a new user and then we also to forward and inform all the connected users that we have a new user joining so we will display this new user in the list of the connected users so here we have send to so we want to send it to a specific topic so here we have slash user SL topic so this is this is a new queue that will be automatically created and we will be sending all the notific ifications or like some type of notifications to this queue all right and now to in order to say that this is the object or the body of our request but in in web sockets we call it a payload so we need to add The annotation payload all right so now let's move on and implement the other method so public user so here we are just returning the user because we need to subscribe to this key Q later on like from the from the front end we need to subscribe to this to this topic or to this queue and in order to receive the notification or if something is happened we need to return some object so that's why we are returning the user because the user contains the information that we want to use in order to display the correct behavior and and UI for our final users all right so then let's call this one disconnect and of course we have now our payload so we understand what I'm writing here and then we have user and then we need to call service. disconnect my user and then I will want to return the user and of course here I will just copy these two and paste it in here so now I will just call this one disconnect user instead of add user disconnect and again I will notify to the same queue that some user is disconnected all right and then we need again to update the list of users and finally we will have a simple get mapping okay so this one I will call it slash users in order to fetch the list of the connected users and I will return a public response entity and of type Ty user or sorry of type list of users and this one we'll call it find connected users all right so and simply I want to return a response entity. okay and then my service doind connected users so we are done with our user controller let's move on and implement the next step of our application now let's move on and implement the chat room so first I will create a new class and I will call it chat room and I will create it in a package I will call it chat room so just to organize by domain my application so here what I need to do first we need our getter method and then our Setter and I will need all arcs Constructor and no arcs Constructor and also Alo the Builder annotation and finally I need the document annotation so now for the chat room we will have a private string ID and this one will be the identifier so let's give it the ID annotation and then we will have a chat room ID or a chat ID and it will be of type string all right then we have the sender ID so private string sender ID and finally private string recipient ID all right so these are the information that we need for our chat room then let's create our chat room service so chat room and then service so I'm going to make this one full screen and of course we need the service annotation and also required AR Constructor so then for the chat room service we will need mainly one method which is to get the chatro ID so here I will create a public and then optional and then it will be an optional of string since we want to just get the chat room ID and I will call it get chat room ID so this is our method and for this chat room ID we will need few parameters so first we need string string sender ID and then I need another string which is the recipient ID and finally I want to add a flag of type Boolean and I will call it create new room if not exists this creates new room if not exists is for the first time when someone sends a message to another one so like when we send a message message for the first time from one user to another all right so if we don't have the chat room we just create it just to reduce the boilerplate code so here what we need to do is we first we need a repository so let's go ahead and create a private and then final and let's call it chat room repository and let's call it chat room repository so we don't have it yet and let's go ahead and create this interface in the same package chat room and now we need to extend repository and then it will be of type chat room and then string all right so now we have our repository and then what we need to do we need to return our chat room repository and then we want to find by sender ID and recipient ID all right so we don't have this method yet but we will create it just in a few seconds so then since we don't have it let's go ahead and create this method and it will be an optional of string find by sender ID and recipient ID so here we don't need the the string but it needs to be a chat room object and the rest will be just fine okay so let's go back here so now if we find the this or now I I will have my Lambda expression in here and now I will create a new room if we don't have it so here if create new chat room if not exists I will do something otherwise I will just return an optional do empty all right so here what we did finding the by sender ID and recipient ID but we are trying to return so this one will return an optional of chat room so we need to map it so here what we want to map our chat room. getet chat ID all right otherwise we will move or like we will do this one so here what I will be doing in case we don't have our chat ID so let's create one so we have chat ID equals create chat ID and this one will be a method provided and we need to and I need to provide the sender ID and the recipient ID all right so let's go ahead and create this method so this one should return the string and then these are the parameters so what we need to do first let's create or format our chat ID so VAR chat ID equals string dot format and then what do we have we have a percent s for the first string and then percent s for the second string and then we have the cender ID and recipient ID so this will create something like this for example we will have Ali and underscore alibu so like this is the sender and this is the recipient ID all right let me remove the X parentheses from here and this is how we are creating or formatting our chat ID then we need to create a chat room object uh not repository but just a chat room and then let's call it sender recipient equals my chat room object. builder. build all right and here I will set get the chat ID which is the chat ID that I just created and then the sender ID which is sender ID and recipient ID which is the recipient ID I just received I will just copy this one and paste it in here and I will call it recipient and then sender so we need to inverse it so what we need to do here so the sender will be the the recipient and the recipient will be the sender so this is what I explained earlier that we want to create two chat rooms one for the sender and one for the recipient by switching the sender and the recipient IDs for each chat room all right so now all I need to do let's here just return our chat ID that we created and then we need our chat room repository Dove and then sender recipient and let's duplicate this one and now it will be recipient sender so now we have this method that will create new chat and then so let me also rename it to chat ID to be consistent so now after creating the new chat I will return an optional dot off and then this chat ID all right so this chat room ID is implemented and ready to be used later on so now let's move on to the most important part of this back end all right now we're done with the implementation of the user and the chat room so let's move on and implement the chat so I we create a package call it chat and then chat I will create an object I will call it chat message or chat messages so here you can we call it chat or chat messages as a package so it's up to you guys so here we need need Getters and we need Setters we need all arcs Constructor we need no arcs Constructor and Builder and finally this needs to be a document all right so here I want to have a private string ID and this one I would like to give it an ID annotation and then I want to have a private string chat ID so this information will receive it from the front end and then we want to have a private string sender ID and then we need also a private string recipient ID and we need of course the content so let's create a private string content so this will be the real message or the content of the message that the users will be sending and finally I will use a date just from java. not local date time I will call it time stamp so you can use also local date time but I just want to use something different each time to show you how to do things or how to use different things all right so now we have our chat message ready let's move on and see what are the methods that we will need in our chat message service the next step is creating a new chat message service so I will create class called it sat message service I'm going to make it full screen and of course we need the service annotation and the required arcs Constructor so here first we need a private final chat message repository this one we don't have it yet so we will create it and let's call it repository and now let's go ahead and create it as an interface so here again we need to extend our repository and for our chat message and of course a string which is the type of our ID we can close this class right now and then we need also to inject our chat message uh sorry not chat message but chat room service so let's call it chat room service and here we need one one method first which is saving the message and we need another one which is finding messages by recipient ID and sender ID so first let's create this one so we will have public chat message and let's call it save so let's call this method save and this save method will receive an object of type chat message as input all right so then we need our chat ID and here we will be using the method this one the get chat room ID from our chat room service that we created just few moments ago so here I will use chat message or uh not chat message but chat room service. getet chatro ID and now I need to provide the sender ID and the recipient ID from this object chat message right here so chat message do get Sender ID and then chat message. get recipient ID all right so let me break this one right here so you can see all the code and here if we don't get anything of course we need the flag so if we don't have a chat room for these couple for this sender and recipient we want to create a new one and then or here let's say just throw and here you you can throw any dedicated exception you want all right here so you can create your own dedicated exception all right so I will leave this up to you and then what I want to do I want to do chat message do set chat ID which is the chat ID we just got from our database and finally repository Dove and then chat message and finally I will return the chat message that we just saved or you can directly return the repository. saave chat message all right so it's up to you here all right so this is how we can save a message then we need to create a second method which is public list of chat messages and let's call it find chat messages and these fine chat messages will take two parameters string sender ID and another string recipient ID all right so then this what this method is so simple so first we need our chat ID equals our chat room service dot get chat room ID and we need to PR the sender and the recipient and now we want to say false in case in case we don't have the room so this one is just about finding the messages not creating a new chat room all right so also I will just break the lines here so you can see everything and then like finally I want to return my chat ID do map since it's an optional if I have have my chat ID what I want to do is my repository and then I have or like I I need to create a method called find by chat ID we will create it in just a few moments or else we can return just a new array list so that we don't have any messages between these two people like between this sender and this recipient now let's create this method and this should return a list of chat message and then that's it now let's import this list right here and this find by chat ID so we want to return all the chat messages from to or from a couple which is sender ID and recipient ID all right so now we are done with the service let's move on and create the controller and see some other things that we want to use and I will explain to you one by one now let's let's create our chat message controller so I will create a new Java class and then I will call it simply chat controller as a simple name so chat controller and then I make it for screen so here let's make it a controller and then of course we will need the required ARS Constructor from lombok and the first thing that we need to do is our chat message service so I will inject private final chat message service and I will call it chat message service so let's start with the easiest method we need right here so we will have a get mapping and this one it will be slash messages and then slash we need the sender ID and we need the recipient ID all right so recipient ID so after that we will have a public response entity and then of type list of chart messages and then we will call this one so let's import this and let's call this one find chat messages all right and here we need one path variable and the first one will be the sender ID and here we will have the string sender ID all right so the second one will be the recipient ID so I will just copy this one to avoid typos and that's it so now simply we want to return a response entity and then do okay and then our chat message Service doind chat message by sender ID and recipient ID so this method is like a classic one nothing fancy in here so now let's move on to the chat mapping or the message mapping which will create each time a new queue for user if it doesn't exist otherwise it will just publish a message to the user Quee all right so here let's create a public void and then we have process method and for to process this message we need to have a payload as we saw before so our payload will be of type chat message all right and let's call it chat message so then what we need to do we have our object set message and let's call it saved message equals our chat message service dot save and then we want to pass our chat message all right then we need something to cue or to publish our message or an object to the queue of the specific user or this the Quee of our recipient ID because processing a message we we'll send a message from the sender to the recipient all right but before that let's not forget to add this annotation here called message mapping and here let's call it/ chat all right so now let's go back to this point in order to send a message or to publish a message to the recipient queue we need to inject some object all right so here I will do private final and our object is of type simp message so it's simp messaging template let's call it messaging template so this is the object that will allow us to send an object or a message to a que all right so here after saving the message I will do our messaging template. convert and send to user since we are sending a topic or a a message to the user queue all right and for this one we need first the user ID as you can see here so string user string destination and object payload so first the user is our our saved message or our chat message. getet recipient ID since we want to send the message to the recipient and then here we want to specify the Q so it will be Q slash messages so this will be formed as and here let's say for example null as an object and we will fix this one just right away so here we want to send a message to the queue so it will be something like that so it will be as we mentioned before John slq slash messages and then John will be subscribing to this specific queue and now for or to send something I want to create a new object and I will call it chat notification so the chat notification will hold the information of the chat ID the sender ID and then the recipient ID all right okay so for that I will just go here right click and then create a new object or a new class and I we call it chat notification so this chat notification will hold the information or a notification for our user or like for the subscriber to our topic okay so this chat notification or this class will have few information first let's start with the annotations we will have of course Getters and then Setters and then all arcs Constructor and no arcs Constructor and finally we want the Builder annotation and then I want to have few information so first I want to have a private string ID so this will be our chat ID or you can also call it chat ID so again we have private string sender ID and we have another string recipient ID and finally we have a private string content okay so let's go back to our controller let me make this full screen again and now let's send or let's notify the user so like this user /q/ messages with this object okay so what we want to send is our chat notification do Builder and and then let's build and here let's provide the information so the ID will be our saved message. get ID and then we have the sender so it will be also the saved message. get Sender ID and we have the recipient ID which is our saved message. getet recipient ID and finally we have our content which is from our saved message also . getet content so you can also get them from the chat message right here so it's like both of them are valid the way you want to get this information so let's remove this semicolon from from here and now we have our back end ready to be consumed by a front-end application so as I mentioned before for this tutorial we will be using simple JavaScript HTML and CSS in order to implement this but as I asked you before just comment on the comment sections if you want to see this application implemented using angular for example so if I see so many people interested in this I will Implement also another front end to consume this back end that we just created together using an angular application or even a react application so I will be waiting for your comments and as Max as I see people post in and commenting out this this is going to motivate me to do that all right so now let's move on to the front end part now for the front end part it will be included already in the same application so here we have the Java resources and then we have this resources and under resources we see that we have two folders first static and then templates so we will be focusing on the static one so here I would will just right click and then I will create a new HTML file and I will call it Index right so this will create an index do. HTML file so here for example if I do an H2 or an H1 so hello from websocket application and if I start the application then it will automatically open this one so I will enable The annotation processing and now the application is up and running as you can see here so I will open my browser and then if I go to the address Local Host uh colum and then 8088 so this is the address of my running application we see here that we have this message hello from websocket application so now this is how spring works so every time we have a file called index.html and the resources and then static so when we open the URL of our application which is Local Host and then the port so it will automatically display and show this file right here so now as a Next Step let's start giving some style and some View and UI to our index.html where we will be displaying the connected users and all the stuff and I will explain it to you just one by one all right so not to make this video too long for nothing and like providing unuseful or unnecessary information so what I did in the background I prepared the UI for you so here we have our user interface and it looks exactly like this one so here we have this title and here you can see my name and we will be having two main blocks so the first one is where the user can write his nickname and real name and then click enter chat room so when clicking on enter chat room this block will be hidden and we will be displaying this one so on the left hand side we will be displaying the online users and here we will have the list of the users down here we will display the connected user full name and we will have a button right here or a link to log out and each time we select a user we will load the messages in here and then we have this input right here to type and send the message so this is how our UI looks like also I would like to show you let's inspect this together and let me show you how this looks like exactly so for example this one the first input which is for the nickname it has an ID called nickname all right and then for the full name we also have an ID called full name and we have this button submit and all this form is inside a form tag called username form all right so here just you need to remember this one because we will need them just later on all right next when we move to this chat container this part right here so it's called chat page and then we have first block we have a user list right here and inside this user list we have this Block online users and then we have a list so this list it has an ID called connected users and in the bottom right here we have these two buttons so the the first one is to display the connected user and the second one is the a or the link to log out the user all right then afterwards on the right hand side we have the chat area so the chat area we have this chat area this place right here it has an ID called chat messages and this where will be displaying the messages from both both users from the connected user and also from the user that will send or like the other side of the chat then we have this form ID and it's called message form and here we have the input where we can type and send our message all right also here among the CSS TI that I have there is a class called hidden so here I just typed it with an underscore but if I bring it back and I give this CL CL a hidden you see now it's no longer displayed and it will be exactly the same here so for example if I add hidden here it will be displayed like that and once the user is logged in so we will remove this hidden class from here and add it to this one right here so it will be this one hidden and it will be the final UI that we will the user will use in order to see and connect and chat with a connected user users all right so this is an an overview of the UI now let me just go back and retell you about the structure so as I mentioned here we have our index.html page and I created a folder for CSS where I have all the CSS for our application you will find all the links and also the source code in the description of this video and then I created also a main.js so this will be our controller where we will have all the logic for for our application and finally this is what I already explained before so the CSS is imported here in the line six so it's just link real style sheet H style sheet and then href and then the the link and there is really important part right here in order to be able to use websocket and also in order to use our main.js so here before the closing body tag we imported three JS scripts I'm going to make it full screen so the first one is the cdnjs cloud fair and so on so forth and it's called sockjs min.js so the version might be different if you search for for recent one but this is what I'm using so sockjs min.js and also I'm using stomp. min.js so these two let's say or let's call them dependencies or libraries are really important in order to be able to use web sockets with with JavaScript so if you don't import these two lines your application might not work all right so now let's move to the action and let's start implementing all the magic of our application so we will implement the the methods one by one and I will explain them also one by one all right so now let's move on all right so in our main.js file the one that we created in here under the JJs folder and imported in our index.html let's start writing our logic so first of all I need to tell JavaScript that we want to use strict so use strict is a directive in JavaScript that enables strict mode in your script function script or functions when strict mode is enabled the JavaScript interpreter enforces a stricter set of rules and generates more helpful error messages this can help you write more reliable and maintainable code by catching common coding mistakes and preventing the use of certain error prone features all right so this is the first thing that we need to do then we need to create a bench of constants so these constants are are mainly the IDS and the objects that we want to get from from here so for example this username form uh the nickname full name and so and so forth so let's start doing this so first I will create the first constant and I will call it username page because we need to handle this one and this one equals document. query selector and then I need to provide the ID so for this one it's the username page and now let's create a second one one so here we have a const and then we have chat page again in the same way uh oops it's document do query selector and then let's use the ID chat page all right don't forget the semicolons it will not be highlighted but I recommend not to forget it even when using JavaScript so the next one is another constant so we will need the username form so equals also in the same way document. query selector and then we need the ID which is username form all right next one we need a const message form so a space in here so message form equals document dot in the same way query selector and then let's do Dash and then message form so I will continue creating all these constants and then I will tell you what are the constants and which one is used for what all right so meanwhile I created these four constants so the first one is the message input this is where we have where the user can type the message and connecting element this for the connection and then we have the chat area and the log out component or the log out link all right so now we need to create a bunch of other variables so first we create the constants and now we need to create some variables so to create variable in JavaScript we use the keyword let or VAR so here we need to First create a stomp client object and assign it to a null value and then we need to create the nickname variable or let's make it lowercase equals null and then we have full name Also let's initialize it to null and finally let's create a variable call it selected user and I will explain what selected user is for later on so equals null and now first things that first thing that we need to do when working with web sockets and stomp so the first thing is to connect all right so the first thing that we need to think about is to connect our user to our website socket so for that I will create a function call it connect and I will pass an event as a parameter so this will be the JavaScript event and here first thing I will just do event. prevent defaults so prevent default means that I want to prevent or to stop the default propagation of this event because I want to manage everything my own so here first we have the nickname let's get it so it's document do query selector and here let's use the nickname ID and then I will duplicate this one this line and this will be the full name and let's change it to full name right here so now this when we want to connect so this connect function will be called when the user hits the enter chat room button so this one so like from this form when the user clicks on enter chat room button so automatically we will call this connect method all right and to in order to be able to connect the user to our web socket we need first to make sure that he correctly type the nickname and the full name all right so here next we need to make a small check so if Nick name and full name so if we have both of these entries we need to use username page and then class list and then add and I want to hide it so I want to add the hidden class that I showcased before to the username page so I want to to hide the username and now I want to show the other one so chat page dot class list do remove and then I want to remove the hidden class all right so let's remove this typo all right so now we change the behavior of the page and what we need to do next is let's create a variable let's call it socket equals a new sockjs and then we need to pass a parameter so the path of our web socket so this is what we configured already in our backend so let me remind you here so when we created the configuration of our web socket so here we said that this is the end point that we want to add with so with sockjs all right so now I guess you can link what we did before and what we are doing right now so now let's say our stomp client equals our stomp so equals stomp do over what exactly okay so it's stomp over our socket okay so it's stomp. over and then we pass the socket as a parameter and finally we say stomp client. connect and then after the connection so we have an object and then we can pass two call back methods so the first one is the output or the first one for example let's say onconnected when so this means when the user is connected to the web socket what we want to do and also we have on error message or our error on error method what we want to do also in case the user is not able to connect to our web socket so for now we don't have this method and we don't have this one so let's first create this so I will create a method called unconnected and I will move it to the bottom just after this one in order to have these two methods together all right but before that before that I want to go to the bottom of this file and here we have the user form name uh the username form sorry the username form I will just rename it because we made it a small typo so the user form I want to add an event listener on it so here I will do add event listener and what is the listener or the event that I want to listen to is the submit event all right so here as you can see we have the form and the type of this button is submit so I want to add an event listener to this one all right so here when the user hits the connect I want to call the connect Method All right so this is what I want to do exactly and here I will pass also through as options all right so now when the user fills his uh nickname and and full name and clicks on enter chat room we will be automatically connected to the websocket and then we will handle the the con the successful connection exactly so we want to handle the successful connection and I will just duplicate this one and rename it to on error and we will implement it just later on all right so now let's implement this unconnected Method All right so what we want to do when the user is connected all right so here the first thing that we do we want to do as I explained before so the user needs to subscribe to his own queue all right so here for example let's say that John is connecting so we need to connect John to this queue all right so this is what we are doing right now all right so in order to do that we need our stomp client and then we have a method called subscribe so we want to subscribe rbe to which queue so I will be using this and I want to subscribe to the queue called user and then I can use dollar and then brackets and then the nick name so since we know that in our backand nick name is the unique identifier of user and then q and then messages all right so in this way we just connected our user to his own queue so each time he will receive a message we will be notified and then after connecting or after subscribing to a method what we need we need a to call another method and I will call it on message received okay so here we need to create a method called or a function called a message received and we will do it just right away so I will prepare it for now and we will implement it later on so here I just just created this on message received function also I will duplicate this line so you remember when we created the user controller we when the user is connected or disconnected we want to send something or to send something some data to this topic or to this queue so which is called user SL topic so I want to subscribe also to that one so here instead of this I want to subscribe to user SL topic so let's say this user SL topic let's assume that it's a public one all right uh or user. public all right so and the same way we want on message received so this me method will handle the any message that will be received from this topic all right so once we subscribe for the different event what we want to do is to register the connected user all right so here we need to to register the connected user and in order to do that let's do stomp client and then send we have a send method and for this send method we can pass the URL so it's app SL user. adduser all right so and this is coming from the user controller it's user. adduser and user. disconnect user and also this app right here is the prefix that we specified in here in our configuration okay so this is the application destination prefix it's SL app that's why here we are using App SL user. adduser all right so now when we connect the user so we say do send and here we need to pass a bench of parameter so here let's we can pass options which is an empty one we don't need to pass any kind of options and now let's do json. stringify so stringify is to transform any object to a Json and here what we want to stringify is our nickname equals our nickname and then we have the full name which is our full name from the variable right here and we can also pass the status which is online as a string all right so now we just connected or we just sent something to the user controller to say that hey register this new user all right so after that we need to find and display the connected users all right okay so let's do this now let's go and write the the code for this method find and display the connected users so here I will create a a function and we call it find and display connected users all right and here I will just call this method and I will say find and display connected users dot then because this one will be an async method uh function all right because we will be calling a backhand so we need to make it an async so here I will create first a const and then I will say connected users response equals and then await so that's why we need the async because we need to await the response from here and then I want to fetch and here I want to fetch slash users and as you can see so this will return a response and this response will contain a Json that contains the list of the users so here I will say let connected users equals weight again and now we we need to wait the response from here. Json all right so now we have the list of the connected users stored in this variable all right so the next one is from the list of the connected users I want to exclude the connected user himself like so for example imagine that Ali is connecting right now and I want to get the list of the connected users from the back end so I want to get all of them except Ali so whether we can do this in the back end or also we can filter it in the front end so this is an occasion to show you how how we can apply some filters all right so this one eal connected users. filter and now for the filter it's a Lambda expression or it's called also U an error function in JavaScript so here I want to make sure that user do nickname so the one with an uppercase is not equals the one or the nickname that we have in lowercase so the the one this is the one that we stored when the user logged in and this one is from the response from our back end from this one right here all right now I will create a constant and I will call it connected users list so for this I'm talking about this list right here right uh sorry I'm talking about this one right here so this UL object so let me go back here equals document do query selector and then let's use the connected users or here we can so as you can see here we used query selector now I want let me show you a different method so let's get element by ID so we can also use get element by by ID and we no longer need this hashtag there all right so now the first thing I want to do is is this connected users list do innerhtml I want to initialize it to an empty HTML so I want to remove everything so now what I want to do from this connected users list so connected users list dot for each and here for each user I want to do something okay so first let me add these semicolons Here and Now I want to create a method I will call it a pend user element all right and this one it will take the user and also it will take the connected users list this one right here so I will show you how this method or this function is going to look like and then I want to make a small test so here after each user I want to insert I want also to insert a separator just to se to separate and display in nicely looking way my connected users so here I want to add a separator for each element except the last one okay so here if my connected users. index of user is less than my connected users. length minus one so this means if we did not yet hit the last element here I won't add a separator so and to add a separator let me show you how this is going to be so here let's add uh an element let's call it separator equals document not doc but document dot create element okay and the element that we want to create is an Li so it's a list a list element and then I want my separator so let me just copy paste this one and then add or first I will get the class list and then add and I will give it a separator class okay all right then I will get the connected users list and then append child and the child that I want to append is my separator all right so now let's move on and create this method right here so create a function and I want to create the global and I will just cut it from here and just move it after this one all right so now let's move on and implement this Method All right so now let's implement this append user element so first let's create a const let's call it list item equals document do create element and the our element will be Li and then our list item let's give it a class so we will call it user underscore item so the all these classes are defined already in the CSS all right so then list item do ID I want to give it an ID so the ID is the user do nickname so I want to give an ID to this element in order to be able and to be easier to get it the next time all right so now I will create a constant and I will call it user image so I will show you the out the final output later on when we finish this code equals document do create element and our element we want it to be of type IMG and then image user or user image do source. SRC equals our image and we will we will place later on an image in our folder called EMG and then let's call let's call it uh even from now user uncore icon.png all right so this is the user image and then for example we can say user image doal equals the user do full name all right so these are just some attributes and some properties I want to create another constant which is the username span so all again document. create element and then span and after that I want to username span. text content so this will hold the information or the user full name user. full name all right then I want to create something so when the user receives a new message from one uh from another user and the user and that specific user is not selected or highlighted I want to display a yellow circle mentioning that there is a new message non uh non read okay so this is what I'm trying to write right now so here uh I will create received messages equals document do create element and this element it's going to be also a span I already prepared the so let me fix this typo I also like have the CSS for this one and then for these received uh messages I will add received messages do text content so I will say it's empty or even let's say zero as you want and then received messages. classlist do add and then I want to add a class I called it MBR so for number MSG for messages and also I want it to be hidden by default and later on I will show you how to display this one all right so now let's add all these items to our list item right here all right so now we have list item. append and the first element we want to append the user image and then again list item do append child and then I want to append the username span and finally I want my list item and then append child and this one is received messages all right and finally this list item itself it needs to be appended to the connected users list right do append child and then list item all right so with this we are done with this append user elements okay so now if we go or if we scroll a little bit up so here we append user and then we add separator only if it's not only if it is the the last one so we don't add a separator in here and now let's go ahead and add other things so now let's start our application and see the changes that we've made so far so I'm going to click on debug and this is going to run my application and then I will go to the browser and I'm going to guide you what we need to do step by step step so here the first thing that you need to do is to go to Local Host and then 8081 and this will open the Express UI and here we need to create the chat app database so here type the database name and then create database so then if you click on it you will find by default this delete me table so let's go ahead and delete it so delete me so now we have Okay so this deletes automatically the database so let's do it afterwards now what we want to do is to open the other browser refresh the the page and here we have our application so I have this one open right here just to trace so here I will just type alibu and alibu Ali as a full name and enter chat room so here we see that we we are redirected to the online users for now nobody is online but we have this look out and we see also that we are not displaying the full name all right so let's go ahead and see what happened wrongly all right so let's go back here let's check we have nothing but let's check what we have here on the connect so here everything seems to be fine and on connected we see that we have nickname and here the nickname which is okay so here we have two issues the first one this nickname uh it's returning the whole the whole element but we want to we want the value and then I want to trim just to remove the spaces and I will do the same here and now here we see this one is slash SL app all right so this is uh where typo and now if I refresh uh or restart the application and if we go again to our browser let's refresh this one and try to connect again so here we see that okay so this one hited a breakpoint so it's saving or persisting a user and in order to make sure that everything is fine let's refresh this one right here so here we see that we have a user table just getting created okay so I can also delete this one so delete me and then if we open this user we see that we have this user right here and we have all this stuff okay so now if I open another Tab and type the 8088 and now for example if I say John and then John do and we see here that you are displaying this user right here so what we want to do next first let's fill some information and what I want to do is when I click on this user right here I want to load all the messages that we have persisted in the database and also display the form where we can send a message and also send a message so let's go ahead and implement this all right so here let's go to this find and display connected user and then we have this append user element so here in line 81 I want to add an event listener to my element so here I will add list item do add event listener and then what is the event that I want to add is Click event and then I will say user item click so this is the method that I want to add so let me copy this name right here and now I will create a function user item click so when I click on a user item I want to do two things first I want to set that item or the click one as an active so I just want to change the background and also remove the hidden from the message form so we display the form where the user can type a message and then Fetch and display the user chat all right so now let's go ahead and do this so first of all I want to do document dot query selector all so I want to query any thing containing this do user and dash item so it's this one so it's this element that we added and this user item and then I want to do a for each and for each item what I want to do is the following so I want to do item. classlist do remove active so I want to remove the active class from everything or from every every element of the list and then I want to add it to the current one so next we have message form do class list do remove and then remove the hidden class so the message form just to remind you is where we have the input and the button send message all right so then I have a const I will create a const and then I will call it clicked user okay so here of course I need my event so my clicked user here equals event. getet current type so current Target okay current Target means the selected or the clicked element okay so then the clicked user. class list do add and then active so I get my clicked element from the event right here I remove first all the active classes from everyone and then just remove the heading class and then add it add active to the current user or the clicked user after that I want to save the selected user so this is the attribute or the variable that we created in the beginning so this will be the selected user that I will be using later on so selected user ID or I'm going to rename it just in a second so it will be clicked user. getet attribute and the attribute ID okay and here I will call it selected user ID and once I get the selected user ID what I want to do I want to fetch and display Fetch and display user chat okay so the user chat is between the connected user and the selected user ID so the collected user is the nickname and the selected user ID is the nickname of the selected user all right so and then then so just like this and now we will create a method or a function just so it will be a sync and then function and then Fetch and display user chat so we will implement it just in a few moments and then I want to update the number of messages okay so here I will create a const again I will call it MBR messages equals my clicked user Dot query selector and then I want to query the element having the class MBR MSG as we defined it before okay so and then MBR message. classlist do add and then hidden since when we click on a user or when we click on the user we just remove the indication or the notification that the user received a message okay so that's it now let's go ahead and implement the Fetch and display user chat all right so let's go ahead and do it all right now let's implement this method Fetch and display user chat so first we need a constant which is the user chat response since we are making a call to our backend so it will be wait and then Fetch and what we want to fetch is slash messages and then we need to pass the recipient ID so let me just use this symbol right here and it will be slash messages and then dollar and then brackets and we have the nickname since he the sender and we have the selected user ID since it's the recipient so selected user ID all right so now we need cont another one user chat it will just hold the response from this one and then user chat response. Json and once we get our response we have the variable that we created which called chat area and then inner HTML and let's make it an empty one so let's empty everything and now we will just start filling the chat so here we have our user chat and then for each so let's call this element chat and then for each element I want to call a message called display message all right and this display message need the chat. sender ID and then the chat. content all right and we will just and we will implement it in one second all right so after that I just want to scroll the user to the B to the top or like to display always the latest message so here we have chat area do scroll [Music] top equals chat area do scroll height so this property right here so now let's create a function Global one I will just move it a little bit to the bottom just after this one and here we have our element all right so so now in order to display a message we need first a const which is a message container so we need to create a message container equals document do create element okay and let's create a div element and then we have our message container. classlist do add and here let's give it a class called message which I already prepared in my HTML and CSS okay so then if the sender ID is the same as the nickname so if it's the same one so we want our message container to give it another class and we call it sender all right I will copy this one else let's give it another one which is receiver okay so this just whether we display it on the left or on the right and with a different color all right so here we have a const message equals our document. create element and then let's create a p element which will hold the message or the content of the message so message do text content equals our content that we received as a parameter from here and then message container do append child our message object and finally our message area or chat area sorry do append child which is our message container so this is how we display a message so we will see everything just in few seconds all right so now we are almost done the only thing that we need to do now is when the user types a message and hits the send button so now we need to add an event listener to that one and send a message all right and also we need to implement the unre received function so the on error we can leave it or can just log an error message but it's not something super important but we need to implement this one all right so let's move on and do it all right now let's scroll to the bottom and now let's say message form and then add event listener and also we want a submit event as we did for the other one and then here let's say send message all right so this send message and then let's give it the option true and now let's create a function called send message and let me place it a little bit up so here maybe before the on receive and the send message we also need our event so first thing is event. prevent default and now what I need to do I need to create a const message content equals our message input the variable or the Conant that we created before do value dot trim All right so this way we are getting the message without spaces like in the beginning and in the end so then if message content if we have our message content and of course we need to check again our stomp client if we still have it or maybe like like it got um initialized to different value so we need to check if we have a stomp client so I will create a const and I will call it chat message equals and now I will have my sender ID which is the nickname so the connected user and then we have the recipient ID the recipient ID is the selected user ID and then we have the the next one which is the content which is my message content and finally we have the timestamp which is we can pass a new date right here all right so then this is the chat and now I can do stomp client. send and I want to send it to/ app SL chat and after that we have empty brackets so like empty options and then Json . stringify and I want to stringify my object right here called chat message and once I send this one I want to call again my display message all right so the display message is from the nickname and the message input value. trim or this message content right here all right so we can use directly message content and of course what we want to do is as we did here so to scroll to the top so let's copy this one and paste it just after this if all right so now sending a message is already implemented so the final thing or the final method that we need to implement is the on message received so when we receive a message what we want to do exactly and then we will start testing the application all right now we want to implement the on message received so this method first of all we need to add the parameter which is the payload all right and here there are several steps that we need to implement and we need to think about so first of all when you receive a message the first thing that we want to do is to update the list of the connected users and see if a new user is already connected or has connected so the first thing we need an wait and then find we need to call the method find and display connected users so when we have a wait of course we need to make the function async so it's an async function and then we want to get the message that we received from this payload so let's create a constant called message equals json.parse and we want to pass the payload do body the body of this payload is the message that we will receive from our or using our web socket so here we want to make a small check if the selected user is not null and if also the selected user ID is the same as the message. sender ID so if the same so this means we check if the selected user or the active user that we selected from the list is the one who sent the message so we need to display our message and here we need to send the message. sender ID and then of course message. content in order to display the message and then we have our chat area do scrolltop equals chat area do scroll height so it's just to scroll and display the latest message just in case so here we want to do something else here if we have the selected user so if the user or like if me for example as the connected user or the one who's using the application clicks on one of the users on the list so in this case I want to set that user active so what I want to do is document do query selector and now I want to select the user with having this ID so Dash and then dollar brackets and here selected user ID since it's the ID of the HTML element do classlist do add and then active all right so I want to set it always to active so I know that this is the user that sent me the message message else what I need to do is just I want to hide the message form so just in case I don't have any selected user I don't want to display the message form where the user can type a message and send it because when we send a message we need to have a selected user all right so in this case I want to have my message form do classlist do add and then h hidden all right so we need to do one final thing so here we have a we want to create a const and we want to call it the notified user so who is the notified user so this means for example if I have three connected users and I'm talking with the first one and the second or the third user sends me a message so I need to show something or I need to notify the user that I received a message from Mr X or Mr y all right so here we need document do query selector and now we need to fetch the sender ID all right so here it will be Dash and then we have message. sender ID so this is the user that notified me or sent me recently a message so now we need to make a check if we have this notified user if this element exists and not notified user do contains active so if it's not already the active user so okay so here notified user. class list contains active so if he's not the active user already I want to set this user active so here I will say uh con MBR messages for example equals notified users or user. query selector and I want to select the class or the element having the class mb- messages or message and then I want to remove the hidden class so here MBR message. class list. remove and then I want to remove the hidden class that I initialized it already in the beginning and also I can say MBR messages. text content equals empty just in order to have some text right here so all right now I have my application and I have everything implemented except one thing that we need also to add but let's start the application and test it so far and afterwards we will add another small functionality and then we will finally test the whole application all right so before we go and testing I just want to inform you that in the background I created a folder and I also um imported an icon here I just called it user icon and it just looks like this so feel free to add it so this one is the image that we precised in here all right so now let's start our application and test the changes so now the app is up and running and now let's open the browser and go back again so the first thing that I will be doing I will be deleting all these tables so here this one chat message I will delete it same for chat room so like we will start from an empty State and finally I will delete the user table all right so now we have nothing we just need to create again our database so let's create it so we have our database here and now I will refresh this page and also I have another one in here so from this side I will connect with a user I named it alibu and then it's Ali Bo Ali and here we see that we no longer or we don't have anymore or yet sorry we don't have yet any connected users but also here we don't see that we are displaying the full name it's a small change we will do it just in a few seconds all right so now I will now connect another user so so this connect or entering the chat room it whether connects an existing user or creates a new one as explained before so here I will call it John do and I will click on enter the chat so here we see that we are displaying here the connected user users but here on the left hand side we see that we are not up updating the list of the connected users for the other one but here if I just refresh and I connect again we see that we have this user right here so when we click on it we see that now it's active so it has a different background and we are displaying the message so if I say hello and send so we see here from the other side or from the jondo user we see that we are displaying here this yellow circle right here means that we have a new message so when I click on this user we see that we have the message and if I for example hello back we are displaying immediately the message from joho and since this joho is already the active user so we are not adding any other message or icon indicating that we have a new message so let's go and try to fix this small issue when the user just connects and also we want to display the name of the connected user and we need to implement the logout so let's start one by one I will display the connected user or the full name of the connected user then we will implement the logout and then we will debug and fix this small issue so let's go and do it all right so now first in order to display the connected username so we need to do it the in the unconnected method so here after registering the user then and before displaying the connected users what we want to do is we need to fetch document document. query selector and then we want to get the connected user full name so here we have connected user full name element and then just text content equals our full name all right so here we just displayed the name of the connected user and now we want to add a logout functionality so the log out functionality we wanted anytime the user clicks on this log out button right here or this log out link I want to log out or disconnect the user from the list so here what I want to do I want to add a log out so here we have already the variable log out. addevent listener and then I want to have a click event and here I will just create a method call it on log out and with the options true all right so let's create our function and let's move it a little bit up all right so here we have our function log out so for the lookout it's a simple one so all I need to do is to call my stomp client and then send a message to the endpoint SL up/ user slisconnect user all right so so user dot disconnect user and then we have empty options and of course I need to send the Json or the user as a Json so this one we can take it from here from the unconnected method I'm going to scroll up so it's around this place yeah so we can copy this one and put it in here so I will just break the line so this one is inside and this is our object so we need to send a new nickname full name and this one the status should be offline instead of an online all right so here and also what I want to do when or after connecting uh or logging out a user I want to do a window dot location do reload so I would just want to reload the page so we redirect the user to the login form again or we can just play with the hidden and the displayed elements all right but we need to uh remove all the list of the users and all the stuff so a Reload is faster also for the log out when the user accidentally reloads the application I want also to inform the backend that this user is getting disconnected so here we can do window dot on before load on before and unload so before loading the page what I want to do here we can use an arrow function and then call the on log out method all right so in this way we are logging out our user when we click on the logout or when the user reloads the page all right so now let's restart the application and test these changes and then we can fix the on display or like the display of our users all right so now let's start our application and go and test the changes that we made for the logout and also displaying the connected user so I will refresh the page here and here so now I will log in again with the user named alibu so here we have this user and I think like the user is was connected from the previous session so let's try to disconnect the user so in order to do that just go to the application and then to the user and here let's select this one and make it offline and save and the same for this John do we can also make it offline and save so now let's refresh and here I will connect with alibu we see we don't have any connected users and now I will connect with jundo from the other side and we see here that first we are displaying the name from for this one and also Alo the name for this one also here if I send a message so for now it will display the user but we want to display the new user each time a user is connected but here we can also double check so for the user I can refresh this page we see that the status for these two users is online but now for example if I click on log out so this user is logged out and now if I refes the page I'm expecting to see this one equals offline so and as you can see so the user now is disconnected but here if I refresh the page or if I sent if like the user still exists in here so this means that when I disconnect or log out or log in again I'm not refreshing this one so let's go ahead and check why we have this issue so now let's go back here so now let's check the unconnected so here the unconnected what we are doing so we are subscribing to the queue of the connected user and then the user SLU so then we have we send a notification to web socket to this queue that a new user is connected so let's go ahead and check the controller the user controller where we have this endpoint and see if everything is all right there so now if I go to user controller make it full screen and here we see that we have add user and then send okay so it's obvious here so send to and here it should be to public not to topic it's user slash public all right now we can restart our application but before restarting let's also log out this user so we have both of them logged out and let's restart our application and go back to the browser and test again so now I'm open back my browser refresh again just in case and now I will connect alibu from this side and here we don't have any connected user we are displaying this user right here and now I will connect joho and I will see if this works so here we see that we have joho getting displayed from here and now just in case for example let me open the same application again and I will connect another user called Alex Hunter so here we see that Alex Hunter is is getting displayed in here and we also have John do so this is the separator that we added between the different users so now for example if Alex Hunter sent a message to alibu so hi alibu and we see that we have a this yellow circle right here showing that we received a message from Alex Hunter so now I can answer him hello there so the message is getting displayed immediately so now if I send from John do a message to Alex Hunter hello Hunter for example and I go back here we see that we have a message from jundo so yeah this is how the application works now let's move on to the next phase that was it for today's video I hope you enjoyed it I hope it was helpful and informative for you so don't miss following me on YouTube channel also help sharing this video help me growing this Channel and I would like to see you also on my website and my social media I will leave you all the links in the description of the video below thank you so much for joining thank you so much for watching and thank you so much for interacting so also as I mentioned before if you would like to see the front end part also with angular please go ahead blow the comments and I will make it for you otherwise I wish you a great day
Info
Channel: Bouali Ali
Views: 23,937
Rating: undefined out of 5
Keywords: spring, spring boot, websocket, web socket, websockets, javascript, chat, chat app, chat application, css, html, java
Id: 7T-HnTE6v64
Channel Id: undefined
Length: 128min 51sec (7731 seconds)
Published: Mon Nov 20 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.