Real-Time Rust: Building WebSockets with Tokio Tungstenite

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back so we haven't done a lot of rust recently on the channel and today we're going to change that and we're going to look at how you can get started with websockets using Tokyo tungsten I now if you've been following this channel recently you know that I've been building an AI agent Network on web sockets a sort of virtual world for large language models and AI agents to go and explore and do interesting things and that is what we're going to continue on in this journey so we are going to build a web soet client using Tokyo Tung tonight which will provide a time service for our AI agent world so before we build our rust websocket client the first thing we need to do is find some sort of public websocket server that we can use just to test everything is okay client side first and then that works we will then continue on to build our time ball so to do that I am going to bring up Postman and then I'm going to select a websocket in Postman and then I'm going to just put in my websocket address now it turns out there's not a lot of websocket servers that are freely available for you to use but there is one at uh websocket doevents in fact specifically it's uh WSS echo. websocket doevents and if you click connect on Postman you see it's going to be connected and then I can just type in something like Hello World here and then click SE send and you see it's echoing back at hello world and and before that you see this sort of echo websocket event sponsored by lob.com now that that works I can go and create my rust uh websocket client against that server and then if everything works okay then I can connect up to my agent Network later and then I can build my time bot so as you can see here I've got a blank directory so I'm just going to create myself a new application by typing in kgu new rust dweb soers at time because ultimately I'm going to be creating a Time bot and as you will see that it has scaffold me up a Ros web sockets at time application and if I just CD into that and now type P cargo run it's going to build that and then it's going to come back in with the standard hello world so now if I open that up in Visual Studio code and we will just uh go to sourc main. RS and then you can see there is the uh print Len hello world so if we look at my cargo. toml you will see at the moment it's a blank application I've got no dependencies specified but I am going to need a few packages as part of my application specifically I'm going to need Tokyo which is the sort of asynchronous runtime framework uh for rust which allows us to do all our kind of async IO and in fact most web servers or any sort of socket Based Services are built on top of Tokyo it is the sort of default standard for Russ and in fact if you check out my video on Tokyo that I did maybe a year ago it's a pretty detailed in-depth explanation of how Tokyo works and you can use it to build uh TCB streams Etc so I recommend you go check that out um we are also going to need a Tokyo ton tonight which is a websocket library that sits on top of the Tokyo framework so somebody's built on top of that as you'd expect and then we need a couple of utility functions uh such as Futures util so to add those packages I'm going to type in cargo ad and I'm going to need Tokyo and specifically I'm going to want uh Full Features so I'm going to do minus uh F and Tokyo SLO I'm also going to need futures util and I'll show you where I'm going to use that a little bit later and I'm also going to need Tokyo tungen night um and specifically I'm going to need the Tokyo tungsten knite and specifically I'm going to need the Tokyo tungsten night/ native TLS feature and the reason I'm going to need that is in order to connect to that server I need access to TLS so remember it said WS that's a secure web socket service and in order to access a secure websocket service I need native TLS feature uh as part of Tokyo Tong tonight so I'm just going to hit return and it will have added those features and if you have a look at my dependencies you see Futures util you see Tokyo version features full and there's Tokyo Tong tonight at Native TLS okay so now that we've done that we're going to go into our men RS and we're going to connect up to that websocket event server that we connect to to earlier so the first thing I need to do is specify the URL of the server we're going to connect to so if you remember that was uh WSS and it was echo. websocket doevents and then for debug purposes I'm just going to stick a sort of uh uh connecting to sort of message so we'll just do print Larn uh and we'll say connecting to and we'll put in our URL so the next thing that we need to do is connect a synchronously to that websocket servers so to connect to that server I need to use the connector async method and you can see that's part of the Tokyo tungsten ey uh package and specifically I need to pass in the URL and then I am going to await it and uh if there's an error of some sort I'm just going to uh come back with failed to connect so specifically connect async is going to return me a websocket stream so I actually want to be able to have access to that later so I am just going to assign this here and take that as a return value now as you can see there's a few squigglies here connect async cannot find the function so if I click on Quick Fix here and select import you will see it's coming from Tokyo tungsten I at connect async now there's a few other squigglies as you can see here as well cannot find function connect async in this scope and that is because I haven't specifically marked out my main function as async so I'm just going to do this as Mark that as async and also because I'm using the Tokyo framework I am going to need to specify that this is now uh Tokyo at Main now if you check out my video on Tokyo that will go into a bit more details on how that works now that that seems to work I just want to be able to uh see if I am connected to the network so I'm just going to say connected uh to agent uh Network cool now that that works if I just do cargo run you can see connecting to WSS Echo we web soer events and then it's telling me it's connected so it's actually made a successful connection so that's pretty cool that we've had success connecting the server but I need to go a little bit further because I want to be able to send and receive messages from that server so what I will need to do is spit up that websocket stream into a write and read stream so to do that I'm just going to say let and we'll put mutable right here and mutable read and and then I'm going to call WS stream and I'm going to call the split function on that and what that essentially is going to do is take that web socket uh stream that we had there and it's going to split it into the right and the read stream now that that's split I can type in something like right do send and then I want to be able to uh pass in a message now I haven't defined my message yet so let's add in a message that I want to say so we'll say let message equals and we'll do message and it's going to be text and we will say something like Aloha uh Echo server and we will just uh take the uh string literal that we've got and then turn it into this message text format and that message text format is actually what the uh tungen knite protocol needs to uh utilize so if I just save here for a second you're going to see there's a few squigglies appearing so if I click on message there and you will uh we click on quick f fix and I just need to import Tokyo Tung night Tung night message and therefore that is going to work here and then you also see on my uh split you can see there's an issue uh there as well so if I click on Quick Fix and if I import Futures util uh stream X so remember earlier we import we added the Futures util package and that is so that we can access uh the uh split functionality so we're in pretty good shape at the moment we've defined our message and as you saw before we were in the middle of uh sending that message to the right stream so so far I've written wr. send message now because it is an a stream I need to do an await on that and then of course if there's any errors I want to get a message so I'll just say that is failed to send message so now that I've done that at this point it should be sending the message you see another red squiggly there I'm just going to uh click on that click on Quick Fix and then you see import Futures sync X so we'll just add that that in and then the r quickly goes and our Imports have been updated to include the right so next thing I want to do is now that I'm writing to the message I'm going to receive responses back and essentially I want to be able to uh write that out to the console so in order to be able to read messages I need to access the read Stream So if I type in something like read next for example that is going to pull the next message off of the stream and then I am going to need to await that but what I now need to be able to do is take whatever comes out of that stream and then read it into a message so I'm going to type in if let some uh message equals read next await so that means that if I do have a message then I'm going to go into this if statement if I don't have a message then I'm going to skip past it so that's good I'm going to have a message and we'll say let message equals at message. expect and we'll say failed to read the message and now that I've got the message I just want to uh write that out so we'll put print line and we'll say uh received a message and then we will just write out whatever that message was and now if I run this we should see receive the message Echo websocket event sponsored by lob.com now remember remember when we accessed this on Postman it sent a a message as soon as we connected and then it did the echo so we just need to change this a little bit so what I am going to do here is I'm going to take this read here I'm going to run this at before the right and then that will show this and now I'm going to read that one more time so it's a little bit duplicat code but it means I'm going to get that sort of sponsored message and then I will get the echo there as well and I'll will just put a bit of a print L here as well to say uh Sending message and then we will say what our message was so in this case it was MSG and now if I rerun this it should tell me what I'm sending there we go so connected received a message sponsored by lob.com send a message Aloha and received a message Aloha Echo web server so I now have built my Russ websocket client so now that that works what we want to do is take this client and connect it into my AI agent Network now if you watch my other video on this as I said I am creating this sort of large language model uh websocket agent Network where there's going to be lots of bots that run in that Network it could be time Bots it could be math bols it could be calculators uh and that will be a place for large language models to go and explore and interact with different agents or different tools so in that video I actually created a a agent server and it was particularly called The Game Server um and therefore you could just connect up your web sop get client to that and then query what other agents were on the network and then be able to send direct message to it so what we will do now is we will start up that server and uh we will connect up our Russ client to that so if I just CD into my game server folder you will see that has uh the bun project for that server and if I type in bun run Source at index. TSX that will fire up my websocket server on Local Host 3000 that game server that agent Network server is actually up on my GitHub so you can just git clone that and then run that locally if you want you will need to install bun for you can check out the video on how to do that so now that that's done I should be able to take this and connect it up to my game server so let's do that so we'll come back into Visual Studio code and I'm going to change that from B WSS to WS uh because I'm running it locally and I'm not running secure uh sockets there and then I will just run this as Local Host at 3,000 um now because my agent network doesn't send any messages when you connect I'm just going to get rid of that initial connection that we have here so that we can then send a message directly to the server so it's the exact same thing here so we will send Aloha Echo server and then we'll send the message and we should get a response so now if I do a cargo run one more time you can see here uh connecting to Local Host 3000 connected agent Network and then I'm sending a message Aloha Echo server and then it receives a message Aloha Echo server as well and the reason that works is that the bun server by default will do an echo if it doesn't recognize any of the command now if I wanted to I could change this from a loha Echo server to who's connected uh that's a specific command that that server understands and then if I send that you can see it returns connected Bots now at the moment there's nothing coming back from this that's because I haven't connected up any of my other bots so we can do that really quickly I will connect into some of my bun Bots and uh within the I've got a Time bot uh already built so if I do a bunun uh index.ts you're going to see it automatically creates a whole load of bots there so you see time bot NYC Unix bot Morse time bot binary bot asky bot assembly script compiler bot again these Bots are up on the uh my GitHub U but now those Bots are connected to my server and if you look at my uh bun server there for a second you see bot registered time bot blah blah BL blah in fact earlier you can even see the the connections we made there so now if I run this again cargo run you can see uh who's connected and now it's got a list of time bot time bot NYC blah blah blah now specifically the time bot that we've created isn't listed as registered in this case actually let's just kill that for a second so we've shut down our Bots we will clear this we'll run this one more time we're back to having no connected Bots and what we will do now is we will will actually connect up our bot uh register as a bot onto This Server so to do that rather than sending who's connected I want to send a register as command and to do that I'm going to have to pass in the bot name as well so I'm going to wrap this into a nice little format macro here I'm going to stick in the bot name and then I will say change this from who's connected to register um as we'll just put some brackets here so that we can pass the bot name in here I'm also going to have to set the bot name so we'll say let bot name uh equals and we'll set the bot name to rust time bot and now if I rerun my cargo run for a second you can see it's now saying connected send register as Ros time bot and now when I send the who's connected message it says received the message recent connected Bots Ross time bot so now not only have I connected to my uh bun websocket server I'm actually registered as a bot on the service and actually if I just run that one more time and you see here um I'm registered as uh be 928 at the end if I come in to my server for a second you can see uh bot registered rust time bot be 928 there's the who's connected sent the message finds out who's the connected Bots and then uh obviously I've finished my connection here so that time bot be 928 gets uh unregistered and then the connection is closed so now that that works I actually want to be able to interact and be able to send my own messages from the command line so I'm going to tidy up this a little bit more and then be able to receive messages so I am going to uh I'm going to keep the register piece here for a second um so what I'm going to do now is I'm just going to clean up this code a little bit I'm going to uh take that sort of registration message and I'm just going to put it into its own method so I am just going to add this register box which just does exactly what we did a second ago and I'm going to remove this here now and now we're just going to uh do that registration here uh within that method rather than uh having all the code sprawling around a bit so all I'm really doing with this uh register bot method is I'm passing in the right stream that we uh that we have created up here and I'm passing in the name of the bot which is Russ time bot and if you look here the uh function is register bot and I'm accepting in that split sync web ciruit stream uh you know which is implementing async right r on pin that's and then I'm also accepting in the bot name and then we're doing exactly what we did before there's a few extra Imports that I need to do to support that but it's all pretty good it's just tidying up my code so next thing I'm going to do is rather than accepting one message and then quitting out what I am now going to do is I'm going to get rid of this and I'm going to add in a new function which is just going to handle any incoming messages so it's going to be called handle incoming messages it's going to take in the uh read stream that we split earlier again it's got the same uh you know signature as we had before and then I've got a while loop so and it's while and I'm going to take in a message and I'm just going to be looping around doing a read. net so it's exactly what we did earlier and then I'm going to match the message and as long as I get a message here I'm just going to write out received the message and of course if I get an error I'm going to say error receiving message so it's pretty much exactly uh what we did before so now that I've done that I can get rid of this single read and I can replace it with my handle incoming uh messages so now that I've replaced that single read with the while loop any messages that come in it's automatically going to kind of push out and finally the last thing I need to do is await the task so that uh the application doesn't quit out before we get a result response so now if I just do a cargo run you can see here I've now connected to WS Local Host 3000 connected to agent Network I've sent the message who's connected and then I've received a message back uh saying rust timeball is connected so we are looking in a pretty good shape at the moment so in fact if I wanted to I could just change this back from my Local Host 3000 and talk back to the public event server and then rerun this one more time and then you would see it connects to Echo web soet events connect agent Network sends a message who's connected I get the received message as uh you know uh sponsored by lob.com and then it's received the message register as Ross time bot and then received the message who's connected remember it's an echo bot so any message I send it's just going to return to me so I sent uh registers uh Ross timeball and I've sent who's connected and he just sent that back to me so that's kind of cool we're in a good shape now next thing that we need to be able to do is be able to send messages or s to the underlying server so to do that rather than me manually sending in the who's connected blah blah blah blah what I'm going to do is change that so that I can just send it in from the CLI so I will just uh have a new function called read and send messages and then as you can see there all it's going to do is uh read in lines from the uh standard input and then then I'm just going to Loop through the reader read the lines and then send the message across to the right stream there so that is literally what it does there's a couple of squiggly issues in there so I'll just add an import statement here which will now solve that and then we have uh all we're doing is importing async buff readex that is going to solve this I can now get rid of this code here and now I can just call my read and send messages um function and of course like before I've spawned this off into a separate task and then stored it here and now I am just going to uh put add that into my join and now if I clear this I run one more time you see I'm connected to agent Network I say who's connected and then it's going to tell me received the message rust time ball is connected so we're looking pretty good now if I were to restart up my earlier bots so if we do a bun run uh index do Ts that is going to add in our time Bots Unix time Bots Mor Bots Etc and now if I type in who's connected one more time I'm going to get a different list so you see I've now got things like the binary time bot and here if I just take this and say at this and say what's the time that message is going to get directed to the binary time bot and you'll see the received message uh the current time in binary is 1 0 z0 whatever and in fact if I can speak to any of the bots so if I want to talk to uh let's say time bot UK which you can imagine tells the time in the UK so I'll say what's the time it will give me the time in uh Europe London 9:00 and of course if I want to speak to time bot NYC is going to give me New York time so at that time what's the time and then it's going to come back and say the current time in America New York is 4 P.M so what's happening underneath the hood there is when I type in at whatever the game server um that I'm running as my bun websocket server is recognizing the at whatever and takes that message and then directs it to the connected bot that with that ID so technically if one of the other websocket server connections put in at uh whatever the rust time bot uh thing is then that would be able to respond if I handle those messages and in fact that's exactly what we're going to do now we are now going to create a Time bot so that we can connect into that websocket server send a message to our rust time bot and then it's going to return the time as per there so uh to do that we will create a new uh uh piece of code so to do that we will cargo new uh Russ web sockets time bot which will be our brand new uh uh time bot so for lin I'm just going to open up visual studio code for laziness I'm going to take this at blank cargo. tomomo uh we're going to paste in the old one one I will just recall this time bot so that's all of our dependencies and then for the main. RS I will just take uh the main RS from the previous project we'll copy that we will uh now come back into uh the previous time bot we'll get rid of the hello world now in this case I don't need to read and send messages because it's just going to send responses so we'll get rid of that we will uh get rid of the read from command line bit here I will get rid of my right handle on the join here we'll stick with the name rust time bot in the uh old version I'll maybe just change that from rust time bot to uh Ross client so that we know the difference so now we will have an interactive application Etc so if I come into here and do a cargo run you can see my application is now registered as Ross time bot so that is good and now what I want to be able to do is handle those incoming messages and send the time back to the sender so I'm going to make a small change here very quickly I'm just going to do an update I'm going to change this from doing a while read next and I'm going to just switch this into a loop and do a match next now it's exactly the same here but I'm just changing it slightly because what I want to do here is pass this par this message uh and be able to extract out the sender ID and then store it in this sender ID variable once I've got that sender ID then I am going to uh essentially um get the current time so you see current time I'm going to get the message current time uh and I'm just going to call local now uh format and get that here so once I've got that format time I'm then going to send the message to the sender yeah so it's going to be at sender ID uh what the current time is which is going to come from local now format which is my current time so if I save that for a second there's a few things I need to do uh first one is I need to implement that parse message data we'll just paste that in for a second and again it's really simple all I'm going to do is look at the message data and I'm going to find the pattern which is comma message at colon and then I'm going to map that out here and then I'm going to do a split to get the ID and then as you see here I'm going to get this kind of let here which is going to tell me what the from is and then I'm going to figure out what the sender is last thing I need to do is as you see I've got a red squiggly on local which means I need some way of accessing the time so I'm going to use a package Chrono so I'll just do a cargo add Chrono that's going to add that into my dependencies uh once that is done I can come back into Visual Studio code so a lot happened there but to recap for a second we connect to the agent Network we are still splitting our streams as we did before we do our register as we did before now I'm handling my incoming messages by calling handle incoming messages I don't need to handle CLI that is gone now obviously I need to pass my read and my WR stream because I'm going to be using both of them because I'm going to be when I get a message coming in I'm going to be sending a response so I need the read and the right channel there and then of course I need to uh await my uh read handle here that comes back so we're in a good space here I'm handling my messages I'm doing the loop that we did before so we're just looping around we're reading messages that come in uh to uh you know from the websocket server and then when I get a message I'm going to parse that data to fi figure out what the sender ID is once I get the sender ID I'm going to be going at whatever the sender ID is to send a message to them and then I'm going to be responding with the current time which is local now format in the current format and again I'm using using the Chrono package to get the local time and then once I've got that formatted message I'm putting that on my right stream and I'm just taking that message that we formatted a second ago and right into the socet that is essentially what is happening and then that parse message data there is really just taking the incoming message and then finding out what the sender ID is so with all that being good if I now do a uh cargo run on this my time bot is now up and running if I do a cargo run on my original time client that is connected the agent Network so we're good if I do a who's connected on my original uh uh client you are going to see that uh Russ client is there which is the one that we just had but if I also pass in uh you can see Ross time bot is there now if I call at Ross time bot and say what's the time it is going to send that message across to uh my Ross time bot there you go so it's going to make the connection to this Ross time bot and it comes back with the current time so it is now part of my agent Network
Info
Channel: Chris Hay
Views: 6,207
Rating: undefined out of 5
Keywords: chris hay, chrishayuk, artificial intelligence, rust, rustlang, websocket tutorial, websockets, tokio tungstenite, tokio, rust tokio, async, streams, tungenstenite, rust programming, rust programming tutorial, async await, rust programming stream, rust programming 2023, rust tokio async, rust tokio chat
Id: p1ES0apOwUw
Channel Id: undefined
Length: 29min 10sec (1750 seconds)
Published: Tue Dec 19 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.