Back to blogYouTube Video

Published August 4, 2025

random coding stream idk

Can't play the video or having issues? Here's the direct link.

AI Summary

In this coding stream, the developer works on 'Go Port,' a Discord-like instant messaging application built with a Go backend and an Electron/React frontend. The session focuses on implementing real-time messaging using WebSockets and a centralized hub for broadcasting messages to connected clients.

Key Takeaways

  • Implemented a Global Hub in Go using a singleton pattern (sync.Once) to manage all active WebSocket connections and broadcast messages to all clients.
  • Developed a messaging pipeline where messages are saved to a database and then serialized into JSON events to be pushed to connected users.
  • Resolved a recurring bug where the server attempted to send messages to closed channels by implementing a 'closed' boolean flag in the client struct.
  • Created a testing suite on the frontend to simulate multiple concurrent users by generating multiple JWT tokens and establishing several WebSocket connections simultaneously.
  • Transitioned authentication token transmission from cookies to URL query parameters to facilitate multi-user testing within a single browser session.

Description

idk what im doing here but come join me anyway

Transcript

Auto-generated transcript
Let me see if this is actually working. Okay, it seems to be working. like I'm live nice oh that's me okay yeah everything seems fine so let's just do this what was I going to do so I'm building this project right now called go port and I guess I'll just continue developing that I wonder if my system can handle this alongside streaming yeah I need to upgrade this I haven't actually built all of these things on camera so I'll probably have to explain all of this beforehand but before anything else let me just open both my folders new window over here this is the back end by the way so let me open the front end as well which is right here there we go so yeah a front end is built with electron and react with my own custom like template that I set up and the backend is built in Go. And what this basically is, it's basically just like Discord an instant messaging app of some sort So what am I going to do now I going to run this Let just do npm run dev And this will launch the app on my machine and then we'll run the backend as well. I'll just use air to do this. so I can get live reloading in my application as well. Okay, we need to wait for the back end to start up. and before the back-end can start we need to start the database so docker container start go code i already have this obviously so that's done now we just give it a minute to for the database to start and then i'll run the back-end and then the front-end and then we'll just catch up on what I've done so far and then just develop whatever is next so yeah so I should be started by now so run air again and okay it's running so that's running now I just need to refresh this and that looks broken I did not build it like that that is weird why are there two server sidebars here Okay so that the first thing I going to fix This is supposed to be the list of servers that you joined just like in Discord So for some reason it being duplicated So let fix that first This is coming from over here Channel view. Okay. And the homepage right now. So. So... Hmm. It's in here somewhere. b2 border art this is that this is the server sidebar okay and then right next to it is another one why because of this okay uh okay so we don't need that uh we can remove this one then i guess i just have an empty div for now Yeah, that's all we need. So I only have one test server right now. And if I click that, it should open up. And you can see, obviously, the UI is not something to be very proud of, but it's not to get started. So what do I need to build next? I need to set up this messaging functionality. And for that, I need to create a hub so that I can listen to all of the WebSocket events. So to do that, let me see. all right so where am i sending these messages right here so this channel message event is where i actually send all of the messages and they get saved into the database right here so once they get saved to the database i want to broadcast them to all of the connected clients now this is kind of complicated because you only want to broadcast this to the clients who are actually viewing this channel right and are also part of this server not to literally every client in the in the database so that kind of complicated and it will need more functionality but just to get started we can broadcast this to all clients just to get started obviously we'll need to fix that later on but so how do we do this I guess first things first I need to create a hub so I'll just go hub.go and just create a hub and this will be a struct it will have clients or connections whatever you want to call it which will just be a list of pointers to the WebSocket client object or struct. And I guess it can also have a send channel that will take a byte slice. And yeah. I think that's all we need. We can create a new constructor function for this. New hub which will just return a hub pointer. There we go. And it will take a list of clients. It will just be a slice of WSClient. We pass that in like this. And we'll just return that. The send will be a new channel that will take bite slices that's all we need now how exactly do we integrate this to our application um is my stream okay yeah it seems okay all right so to actually make this work we need to when a new client connects we need to pass that into the hub and we need to make sure that we're creating that was storing like this global state of hub so to do that we need to go to ws over here this is where all the of the clients get connected so i guess every time the client gets connected we need to store them in the hub you can create a global variable here to handle this uh and i'll just call this hub and this is coming from the web utils package the web utils new hub and we don't have a list of clients right now so i'll just pass in an empty list for now and then every time a new client is connected we will add that to the hub hub.clients.append client or pointer to the client. There we go. Now every time the client connects to the server, it should get added to this hub.clients list. So let's confirm that and then we can actually build everything else so I'll just create a temporary function here that will just print the hub client so I guess we can just do a time dot new ticker time.second every three seconds let's just say so for select t case this how you do it right from t dot prince ln up dot clients and then we just call this okay so we do that and then refresh this and then let see what we have okay so we do have something over here we do have one connection and and this is obviously just a memory address so if i just print this a bit more i guess cleanly range up dot clients and C will be pointer so we'll dereference that and I guess we can print the user and let's see what we get over here refresh this to reconnect the web socket and then let's see so yeah we do get the actual user so this is actually definitely working but this is not going to be unique so let me print the actual address dot string there we go uh what's the error here Let me just do this. Let's print this. okay and yeah we get this so there is definitely a connection here and if i refresh this as well this is not going to work because electron doesn't have that isn't logged in that's a separate issue but yeah this does work i want to see what the remote address is as well and what that gives us let's quickly look at that as well and then let's see okay refresh this okay so this is definitely working now I can remove this go routine now and let's see what comes next so we have a hub now and now all we need to do is go back to channel message and once we built the actual message and stored it in the database here we can send it to the hub so to get the hub you know what we should do actually where is it yeah instead of having a hub over here we should have it in the actual web utils package so we'll say hub over here and we'll create a function called get hub not github github so yeah um and this will return a hub object and instead of this we'll have a hub over here there we go and actually not like this but like this okay and what this will do is use a once where is it for once sync dot once just so we only run this one time and never again so once dot do and this will return the hub as such it will assign the hub to this and there we go there we go okay um and then this will just be an empty list of clients once that's done it will return the hub or like a reference to the hub and we don't need this new hub anymore and there we go now this should work all this will do is just the first time we run this it will create an empty hub object and every time we run it run it again it will just return that existing hub object so that all good and this is the same pattern i use in the database code as well So like you see over here we have the connect function which returns a pointer to the database And we just declare the database pointer up here along with the sync.once. And then we just connect to the database once. And then we return the database every time we call this. So that's how that works. And actually, this should be a pointer instead of a copy. so change this as well and remove this and there we go now this is complete now we need to get webutils. and i guess we need to change the name of this as well so it can be exported we'll call this global hub now i should be able to import this as well there we go equals or rather end client pointer there we go okay that's not working oh wait that's the that's the wrong file uh back to ws there we go so that works and now we can actually send it over to wherever we want to send this. So we need to broadcast this to every single client inside of the Global Hub. So we'll get the Global Hub like this. We'll use the send, obviously. And let's see. How would I do this in the actual clients? Let me see. so this is happening in the WS file okay so we have a send channel we Which gets listened to by all of these. So, okay. Which means to run this, we will actually need to, I guess we don't need the hub to actually be like to have a send channel. It's gonna actually just be a function, I guess. A function that just takes a byte slice and it doesn't need to return anything. So this can just be empty for now. And I'll define a function up here. What this needs to do is func send to clients. And this will obviously take the actual data, which will be as such. and then it will just loop over all of the clients using range uh and i guess they should have it should be a receiver of some sort h global hub pointer h dot clients clients like this okay lines and then we just c dot send the data there we go okay now this send function will just be the h dot send to clients okay so that didn't work either What am I doing wrong? Oh, all right. Uh, instead of this send function, we don't even need this anymore. We can just call this send to clients, capitalize it like this. So it can be exported and then we can just use that. So if I go back over here, we just do send to clients and then we can just do it at data. So what this going to look like is if I do like let me see what I have over here and okay so this is a utility function and what this does is it will first get the JSON of any given object and then return it as either a list or a map. That's kind of useful, but what do we need over here? We need to serialize this message first and then just return that. The way to do this is to do, let's say, res equals JSON.martial the message. and let's handle the error as well log dot print ln martial error error now we'll return the rest over here and that should work so what this should do is send this message to all the clients that are connected let's make sure that it works we'll um go over here refresh this to reconnect the socket and am I still on okay it looks like I'm still on awesome uh we'll go to this server and where is everything oh there's an error okay uh invalid memory address or no points or dereference let me see Where is this coming from? Oh, over here. Okay. What was it? line 59 okay which is right here all right um valid memorators and no points of reference okay this is supposed to be oh wait wait we actually supposed to not use it like this it's supposed to be get hub get the hub and then assign this to hub.clients like this because if we don't call getHub then we're not going to like create and initialize this whole list of clients right so that's the problem here okay refresh all of that and let's go again and this time it works awesome no errors perfect now I'll a message hello there and it should get sent see if it got sent slow as to who cares okay so the message did get sent let me just make sure that it did we can go into the database and just run bash inside and we'll just select everything messages and yeah this is the one that i just created awesome and yeah everything is perfect here so that's working now did i get the event um no i did no or i did actually yeah i did here we go okay let me just pre-print this so it's easier to see and yeah there we go so we sent the message over here and then it gave us this stuff back now this isn't in the format that it actually needs to be so i need to fix that every time we send a message we need to send it as a ws event object so this is not fine as of yet uh i just call this serialized message The response will be a WS event with the type of the types dot channel message and the payload is going to be the actual message. and this is going to be the serialized version of this awesome so and we're going to return that perfect i'll call this reply and instead of json.marshall here we'll use web utils and serialize struct we'll serialize the message this will return an error we will we will handle the error over here and then if we need to use a type assertion here serialized if let's just say if s okay equals serialized dot and this is uh this is going to be a map string of any then we will run all of this and let me add the condition as well the rest is going to be JSON.martial reply if error does not equal to nil log.println martial error print the error and return and if we get an error up here then return as well and up here as well we don't need to continue executing if we if we get an error let's handle the else case over here as well um invalid serialized value let's just say and then return perfect so that's done and now let's fix this error okay missing type uh this is going to be a map string any like this this should be be a string and there we go now I should get a good response back let me build this and there we go now let's refresh this awesome now i'll send another message actually before i do that i want to actually display these messages as well so let me just send this and let's see what we get back okay we got the message back it got saved as well and here it is this is going to be a type channel message this is the reply from the server and this is the message object we have the text id channel it was sent to the author who created it everything we need awesome so now we have now all of the connected clients can get messages so the next thing we need to do is actually display these messages and create like a chat interface so let's do that next for this i need to go to the front-end code base and then just design this whole thing so just give me a second all right how do we do this uh i guess we need to go to the channel view then this is where all of this channel stuff is being displayed and this div right here is where we're going to display all of the messages so first of all let's go over here and okay i guess we don't need to subscribe over here instead of this i guess we can do the subscription stuff on the channel view over here. Grab this and place that here import everything I don need these so I just remove them okay so just to confirm that this is still working let me console.log payload which is going to be an object i've lost a message uh it's going to be a payload which will have a message attribute and inside that message will be text so you can print that and i guess message from user we can print that as well and let's just see if this is working so i guess i need to now refresh the page and send something again and there we go it did get sent and okay but I don't see the actual message here and we get an error over here so what just happened send on closed channel that makes no sense on line 63 over here it's not supposed to be closed you probably got an error somewhere over here okay okay got it so the error is on the front end got it uh else execute send okay this is probably happening over here Mm-hmm. Mm-hmm. In server sidebar. uh where is this okay over here all right this is what's failing um let me let me build this again i'm gonna refresh okay now it works we have everything we need we'll send a message message from user there we go so this does get perfectly used okay perfect so i don't know what that was but okay this is working and we get the message over here now we need to actually display this right here so i guess i'll create a list of messages in state over here messages and set messages i'll use state this So just be an empty list for now and i'll also add type definitions for this. will say each message can have an ID. and Let me see not this. Where is my message model? There we go. It can have an ID. It will have an author, which will be the user object. And it will have a channel, which will be the channel object. And then it will have a text. OK. Let's add these. We need the author, which is the user. We need the channel, which is a channel. All of these types are defined up here as well. well so that's great then we'll have the text which will be a string and a couple more fields that come from this base class we also need to have the created at and yeah this is just a created at okay created at This is what that going to be like And it going to be a daytime object Let me see. Let me make sure. It's not here. Okay. Let me send it again. Okay. Did I not get a reply? Oh, I did not get a reply. Okay. Okay, so there's clearly an issue with the way our hub is working. For some reason, it just disconnects all of our clients. I don't know why. We need to fix that. Somehow, the clients just keep getting disconnected. somehow this keeps getting disconnected there's nothing here to actually disconnect the client i don't know why it keeps doing that handle channel events read from channel message okay and it tries to send the message to the client and turns out that the channel is closed for some reason okay this makes no sense Let me ask JPD. Thank you. Let's see. you these are good solutions but it doesn't actually fix the real problem here I'll remove this field for now. And before we do anything else, I want to fix this error. So, run this again. And this is where we're actually sending this. Okay. So, let me log a couple more things before we proceed. Let's log the client's remote address and the client's username. There we go. and let's say sending from hub or just broadcasting to these clients perfect let's build and run this I'll close this refresh reconnect it and just send a message we got a message back perfect and in the logs we can see that we actually are sending it perfectly fine Okay if I send it again it works again What the hell And why is it working the first time? It keeps sending new messages. What the hell, man? So for some reason, it wasn't working before, but now it's working perfectly. after I added a log this makes no sense okay well anyway since that's working I guess I guess what happened oh I got it there wasn't actually a bug what what basically happened was when we were changing stuff in this front-end code it got recompiled and regenerated which closed the web socket connection but obviously the the the back end doesn't know that so it tried to send on a closed connection and that's why we kept getting those errors so yeah that was the problem everything is working fine that's good to see now let me see yeah so they have a created ad field and that's a date time and we can just use that to actually parse this. What's the TypeScript equivalent for dates? Okay, there we go. So now we have a message object, which we will have over here. We'll say this is going to be a list of messages. And we'll import this from API Utils. and see it recompiled because i made a change and now the web socket connection will be closed over here uh and if i try to send a message now it will fail so if i do it again or not maybe it'll just keep working well Okay, web sockets are confusing. Never mind. So we get the message over here in the payload.message object. What we're going to do is append it to the messages list. So we'll say set messages equals the previous list of messages. And we return how do you use the spread operator in TypeScript again We going to do previous I guess like this Actually this is a list So previous and maybe like this Okay like that That along with payload There we go Now we have a list of messages here. And just as a basic implementation for now, we're going to say messages.map and we'll create a div here. Obviously give it an index, a key, so React doesn't complain. And then we're going to actually display this so what kind of a design do I want here go with something simple for now and username m.created at uh how do you display to locale jstrain i'm pretty sure this is how you do it right okay i want both of these to be in flex all right and right here we're going to display the actual message and that should be it okay so now i can refresh this and websocket is connected we'll say hello again and it closed for some reason why did it close uh let's close this this. So there is some Oh, wait, wait, nevermind. Now I actually figured this error out. What's going on is every time we refresh this the reason it stops working is because it creates a new WebSocket connection Every time we refresh the content page it creates a new web socket connection but the hub actually stores the old web socket connection which is why it tries to send on that old connection and it just fails so i guess we do need to handle this now so how did gpd tell me to do this we basically just need to use select and add a default case so that's pretty simple all we need over here is to do select and case will be wait I'm sending over here not reading so okay so that does work awesome um c dot send the rest and then over here the data and otherwise we'll have a default case which will be log by print ln same thing over here but but connection close all, all. Let's just say that, just to have better logs and everything. So this should work now without any errors. And yeah. What's remaining over here? Oh, okay. Remaining. Okay. Wait, why do you have a remaining over here? That makes no sense. OK, the active appliance. All right. So we send the data to a channel, to a connection, and then we just store that as an active connection in this list over here. I don't need to go that far for now. So I'll just do a refresh this again. and send a message and locale date string is not a function. Okay. So why is it not a function? Is it just, wait, is it because it's a string date? Wait. So I'm supposed to convert that to a to an actual like say convert string into a date in typescript okay so that's that's pretty simple stop opening random stuff and go back over here so this is probably a string then and we need to take it from us from a date we'll do a new date and then we will actually print this as such now it should be fine let it all recompile and refresh this open up the console hello let's send that and it closed again okay there is still a problem in my hub it's still trying to send to a closed channel why on line 18 over here why is it doing that i mean if the channel is closed isn't it supposed to just go to the next to the default case I thought it would just move to the default case if the channel was closed. Okay. So this is kind of a pain because the channels get closed every time we... um channels get closed in this file over here we run deferred.close when we can't read or write to the channel it just closes everything for us and this happens for individual clients but i guess what would be uh useful if we have i guess we can have a like a closed boolean over here and when we run this close function it should update that c dot closed to true and by default it should be it should be false so that should be fine okay and i pretty sure the default value for booleans in go is false right just let me confirm that the default value for booleans and go should be false um yeah it's false perfect okay so that's fine as well now and in the where is it in here in here we will instead of having this we can just go and do what we had before and close that if the c dot closed equals true then we're not going to send it otherwise if it is false if the connection is still open then we will send the data and in here we will just say connection closed or full i guess i guess we don't need this condition either there we go let's rebuild this perfect okay now i should not get any errors in my in the in the hub anymore let's see okay and there's my message hello and what's up there we go it took a second over there but yeah so i can just keep typing and keep sending messages like this and okay perfect so what i do want to do is space these out a bit more and also just um improve the ui and also try to test this with multiple like users which i don't have right now so I need to figure out how to do that as well. But for now what we're going to do is just turn this into a flex column and add some spacing between each message. And since this will refresh it will remove all the messages we have. I just say close it again please don Okay another error nice I don get it why is this still happening does it not get marked as closed over here this makes no sense Okay, so that's still a recurring bug and we need to fix that. But the actual messaging functionality works. We do need to fix this bug. I don't know why it keeps closing this channel again and again, but we do need to fix that. And once that is fixed, we can move on to, I guess, creating multiple clients and then just trying to have a conversation here. So let's try to do that. keeps getting closed i don't know why oh wait oh oh oh oh it did say the connection is closed or full right here but then i keep trying to send the data anyway that's that's the problem there we go okay it's good to see that this log did fire that means that my closed boolean over here is doing its job properly so now that error should not occur at all i'm pretty i'm 100 sure that it should not occur anymore right right there we go i'll just keep sending a bunch of messages here then i'll refresh the page and then i'll try sending a message again okay and it's still working awesome perfect Okay there we go So it all working perfect Slow SQL who cares This is probably slow because it all running on my local machine and yeah obviously in production we can like disperse all these different services into different servers and everything but for local development this is fine so yeah the messaging works now i need to somehow figure out how to like create different clients and just be able to test with that instead of just be just being me uh because right now i only have one user over here i don't have multiple machines to do this for me so i guess what i can do is first of all create like two or three new users and once i have those users i need to somehow log in as each user simultaneously at the same time and then i need to send messages through them doing this manually would be a waste of time so how can i automate this I guess let's just start by creating a bunch of users first right I can go to the sign up page and yeah I like this design I guess we can have testuser1 at email.com and we'll say testuser1 testuser1. Cool. Okay, successfully submitted. We'll do another testuser. And I'm pretty sure all these are being created, but let me see. Okay, let's create access user tree as well. Okay, all of them are being created. Perfect. Now we have at least four users in our database and we can confirm that. right here if i select everything from the users table yeah we have them all awesome so so we have a bunch of users now we need to actually connect them and then send those messages so in order to do this what i should do is i should create jw jw uh what am i saying jwt tokens for every single user and once we do that then we can see what comes next all right anyway uh okay so the plan is simple we go over to the app the main code over here i'll just comment all of this out we don't need this right now and we don't need this either we'll get the database and we'll select all of the users in the database right now and we'll start user db.select everything, find context.background and this will return a bunch of users right let me see yeah it'll return a bunch of users and an error okay so let's handle the error error getting users and then we log the error and then for every user over here I want to generate a JWT token for this user which will be u this will return the token and then error will handle the error as well error generating jwt will print the user's username and will print the error now we have a token so now what we can do is print f the token string combined with the user's username okay all right okay um the username along with the token string. There we go. Let me just make sure that all of this works. And it does. I should probably add a new line over here just to make this easier to view. There we go. So we can create a bunch of JWT tokens for all of these. Now we somehow need to send these over to the server and connect all of these clients simultaneously, not one at a time. uh how do i do this i can get the jwg tokens but i don't know how to actually uh because the problem is that this this token gets sent via a cookie and that cookies value is token all the time and even if i open up multiple browser windows that cookie is going to be the same so the only way to really do this is to like send the token inside of the request data or something and i guess that way you could create a new connection but it's still kind of wonky so it's that's not good enough so that's still pretty difficult to to do and like how long have i been alive anyway okay for a whole hour nice uh so how do i implement this it super complicated um i think the easiest solution would be to um create to to change this uh functionality so that the token is read not from the cookies but from the uh request data or something so over here and we can actually obviously change that back as well so right here we get the token cookie um i guess we can't do it like that uh what we can do is say token equals to token cookie dot value and over here instead of using this we'll use this there we go and now instead of using token cookie we need to use um the request data so what can i do here yeah uh we'll just use request.as body let me create a struct first just a struct to there we go call this vs upgrade request this will be a struct, it will have a token as such, which will be a string and we'll say web utils because i have a utility function for this so decode request into this upgrade request struct and the request is just the request body what does this return it returns the request and the error okay rec and error if error does not equal to nil you can see that went ln error and return we can comment this out and the token can just be the request there we go now it should read from the request and now in my front end what we can do where is my front end there it is what we can do here is create um so this channel view is just going to keep listening to the channel messages right so that's not a problem what we can do is go to the um or actually right here what we can do is Let me see how I actually created this. Okay. Um, alright. So, in the second tab, let me open up Channel View again. And what we need to do is create four WebSocket connections. One for each client, or each user. and we'll assign them those JWT tokens that we created earlier and then we'll just use that we'll use those we'll send them to the backend and it will consider them users and then we can just yeah then we can automate this and see how it works in a like a real conversation between different users so So let's do that. First things first, I need to create another use effect over here. I could just do it in the same effect up here, but I don't want to do that. So I will have an empty dependency array. and we'll say this will have I guess first of all we need to create a list of clients probably. So we'll say clients equals a list of objects and I can actually just put this outside of the component up here and this will have it's a socket which can just be new web socket to websocket localhost 8000 slash ws there we go and then it comes also have like a token which will just be whatever i guess and then we just duplicate this four times there we go and let's see let's regenerate these tokens um here we go there we go and awesome so we have all these clients now and what we're going to do is for each client in here. We're going to send messages with it. I guess it's going to give me a client. All I'm going to do with this is I'm going to turn the socket on. Well, not even the socket. What I'm going to do is socket.send and then we're going to send a message over there. How do we do that? Okay, json.stringify data. And the data is obviously a ws-event object. So, let's say const data equals a ws-event, which looks like okay there we go so this is going to be it's going to have a type uh this is going to have a type and it's going to be channel message the payload is going to be uh what was it let me see in channel messages over here. The payload that I expect to have is channel ID and text Okay So the channel ID and the text We can obviously just hard code some of these things so channel id can just be one i guess and text can just be whatever hello there who gets it okay that's the payload and then we need to have a message which is optional so i'm not even going going to bother with it there we go and it's going to be json.stringify data and that should work perfect so all the clients are going to send these messages as soon as they're ready now what comes next after this so we're going to send all these messages and then we also have a channel view which is obviously always listening let me show you so this loop over here is going to keep sending messages from each client and we also have we also render all of the messages up here and we subscribe to the channel message event to get every single new message so all in all this should work fine assuming that i coded this correctly and yeah and hopefully this works as well then it should be fine okay now we can actually run this and see how far we got and okay never mind i need to unclament the actual code over here and we can remove all of this now run this okay it's already in use we need to kill that command uh i forgot the actual command for this so let me find this yeah okay um fuser dash k there we go kill that old server and then run this perfect so now the backend is running now i go back to the channel over here and okay none of these are connecting for some reason they all failing fail to read data okay wait where is this error coming from okay it's coming from over here all right oh okay why is that happening am i not sending it correctly or what oh wait wait wait in websocket requests i don't think you can send these requests any request data anyway uh your websocket can i send anything in the request data i probably can't i don't yeah see you can't send custom data okay the handshake does not support our first party all right what we can do is send tokens like these perfect so we can do that and we can get that in go from url.query perfect um so let's do that instead what we're going to do is we're going to change this to where am I? Go to WS. Instead of trying to decode the request, we'll say r.url.query.get token. This will give us the token that we need. And we don't need this anymore. So that should be fine. And what I'm going to do next, save this. What I'm going to do next is, why is this not saved? There we go. Now we can actually go to the front end and add this token to the URL instead. So, kind of a kind of a problem here because this is a little extra boilerplate. So what I'm going to do is just Remove these. We'll change this socket to socket URL. And what I'm going to do is declare a socket over here. And a socket is new web socket It going to be the c dot socket url plus plus question mark token and then the token and let me change this to back text so this works there we go uh the token is going to be c dot token that's going to be the socket perfect then we just send it and yeah now this should be fine let's refresh okay invalid number of segments okay okay oh yeah i guess i also need to change the uh change how i send the initial token so to do that first i need water but to do that we need to go to the the website with context i guess there we go and over here we need to actually have the token inside the url Or I guess we can also just handle both cases in here if we really need to. It's like we can do something like var turpin string and... Does this get return anything else? can I get a, I probably can't even get an okay value, right? Yeah, I can't get an okay value over here. Does it have, okay, perfect. So we can use the has, has token. Then this is the token. Otherwise, this will be the token. and instead of creating new variables we'll just reassign them perfect so now let's run this and there we go let's refresh sweet okay so that definitely works but oh I'm logged in as test user three now okay let's go back to uh websocket context over here channel view this is probably the old JWT for my user I'm going to get that back then refresh just so i can get my server back there we go so that's my server and okay still in connecting state got it so that's that's coming from over here and over here if socket.readyState what is this, a boolean? it's a number, how do you use this again? if socket.open, okay it's not equal if socket.open can I just sleep? how do you do sleep? I guess you can't do time, but sleep instead of this let's just wait for like one second and then send the message that should be enough time i think and let's just wait for one second over here perfect uh okay and there we go awesome so now we getting messages from different users and they all showing up over here Perfect And if I refresh this and there we go. Yeah. So basically different users can join this channel and send their own messages and they will all show up here because all of these different connected clients are going to the same hub and that hub is going to then broadcast messages to all of the connected clients so this is great as like a basic implementation and i need to stop this now this is it's getting out of hand yeah this is great as like a basic implementation obviously we need to um upgrade this even more like for instance we don't have the channel history over here so that's obviously a problem as well let me refresh this i've created like 200 messages but obviously there's a lot more to do the next thing we need to do is to actually like um show the channel history every time we like open up the channel for the first time and we also need to improve the ui right now it looks very basic and like 1200 other things like that so a lot of work to do on this project but i'm gonna end the stream right now i think that's enough for today and uh yeah i might do some off-camera coding on this just because why not but uh yeah that's it for today Thank you.

Share this article

All great things started with a conversation

If you've got a cool project or opportunity and you want me to be a part of it, set up a free meeting with me here, and let's talk. 😊