Simple TCP Chat Room in Java
Skills:
AI Pair Programming80%
Key Takeaways
The video demonstrates how to build a simple TCP chat room in Java, covering the basics of network programming and socket communication in Java.
Full Transcript
[Music] what is going on guys welcome back in this video we're going to build a simple tcp chat room in java so we're going to have one central server and multiple clients are going to connect to that server they're going to be able to exchange messages to change their nicknames to leave the server and we're going to build this in java this is the first time actually we use java on this channel we have used python c c plus go even assembly but never java and you know probably that i'm not the biggest java fan but i think it's interesting to build a tcp chat in java because it's quite different than doing this in python or c python c are quite similar when it gets to when it comes to sockets so we have the same keywords sockstream afinet we have a very similar type of using sockets a very similar way of using sockets in python and c in java it's quite different we have buffered readers and print writers we have sockets server sockets and we have a whole different type of multi-threading uh and compared to python we have multi-threading in the first place because python is limited by the global interpreter log and because of that we're going to build this today in java so let's get right into it uh we're going to start by creating a server file so we're going to create a new server class like that and this class is going to implement the runnable interface because runnable basically means that this class can now be passed to a threat or a threat pool and can be executed concurrently alongside other runnable classes or other classes that implement a runnable interface and if we implement runnable this means that we need to implement the run function so we need to overwrite this and we need to say public void run and in here we have the code that is executed when we run or start the runnable class so the idea here in java is that we create a thread and instead of passing a function like we do it in python in java we cannot pass functions because they're not first class entities in in java we pass the whole class and this class has to be runnable and when we pass it we can then call this run function all right so what we're going to do here is a basic idea is we're going to have the server and the server is going to constantly listen for incoming connections so for client requests to connect and then it's going to accept these connection requests and then we're going to open a new connection handler for each client that connects so we're going to have an inner class where actually we can start coding it already we're going to have an inner class called connection handler and this class is also going to implement runnable so it's also going to have its own run function we can also implement it with a click here um and this function uh this class here is going to be what handles the client connection so we're going to pass the client to it and then it's going to handle the individual connections that we accept here so first of all we're going to create a server socket for the server itself and this is going to be a new server socket and all we need to pass here in java is actually the port number we don't need to pass an internet address an ip address unless you want to specify one manually uh but we only have to pass the port so this in this case we're going to listen on nine nine nine nine uh and as you can see here we already have to catch a io exception so this is something that we always need to do in java when we use something like writers or readers buffer readers print writers or sockets we always need to catch io exceptions so we have a try block if an exception is wrong we're going to go to the catch block and in this case this just prints the exception and ignores it uh we can also you know handle it in a way so i'm going to remove this actually and i'm going to say to do handle like that because later on we're going to have a shutdown function now this server has the accept method and this accept method returns a client socket so i can go ahead and say socket client equals and then server dot accept so when we accept the connection we get a socket here of course don't forget to import all these it imports them automatically if you use intellij uh so java io io exception and java net service socket and socket and now we want to do is we don't want to deal with the client in here we want to open a new instance of the connection handler instead of handling it here because we need to handle multiple clients concurrently and because of that we're going to define a constructor here we're going to say public connection handler and we're going to pass a socket which is going to be the client that we're going to deal with and we're also going to have a private socket client here and then we're going to say this dot client equals client there you go and what we're also going to do is we're going to define a buffered reader which is going to be in and we're going to define a print writer which is going to be out so the buffered reader is what we're going to use to get the stream from the socket so when the client sends something we're going to get it from in and when we run i want to write something to the client we're going to use out now in the run function what we want to do is we want to also open up a try catch block because we're going to have to catch i o exceptions so i owe exception e come on and we're going to also add to do handle here and in the try block what we're going to do is we're going to deal with the client so first of all we're going to initialize the out and in streams that we have here so the reader into writer and for that we're basically just going to say out equals new print writer to the print writer we need to pass an output stream uh we can get this directly from the client and we're going to set auto flush to true so we don't need to always manually flush the output stream in order to actually send the messages uh we're going to also say in equals by the way let me just check real quick if i'm not blocking anything here with my camera i'm not uh all right so in is going to be a new buffered reader and the buffer tweeter is going to be um you have to pass an input stream reader and to this input stream reader again you need to pass an input stream and the input stream is what you get from the client so client.get input stream then we pass this to the input stream reader and then we make a buffer tweeter out of it so those are the two things now that we can use and all we need to do now to send something to the client is we need to say out dot print line uh out dot print line like that so this is how i say hello to the client and if i want to get a message from the client i just say in dot read line and then i can print it with system out print line um so what we want to do first is we want to send to the client a prompt that asks for a nickname so we're going to say out dot print line please enter a nick name like that and then we're going to wait for an input from the client so we're going to say the nickname actually this should be a private string up here private nickname private string nickname sorry um we're going to say that this nickname is just in dot read line so whatever the client sends after this now of course if you're building a professional chat not just for a video you can also do all sorts of edge cases so you can check is the string empty is it full of spaces um is this a valid nickname is it too long and so on those are just if else with string functions so i'm not going to bother doing that here uh all you need to do is you need to say okay actually after that if the nickname is not null and if the nickname uh contains and is whatever is blank whatever um you can play around with that if you want to i'm just gonna assume that the client is going to enter a valid nickname so i don't have to waste the time here on a thousand if statements uh and then we're going to just say as a server lock so this is just for us as a server uh we're going to say nick name connected this is just for us now what we also want to do is we want to broadcast this to all the other clients for that we're going to need a list of clients that are connected and because of that we're going to go to the server here and we're going to create a private array list full of not strings but connection handlers and this is going to be the connections list of course we need to import the list so import the class here and whenever we create a new client what we want to do is we want to say connections dot add and actually want to add the connection handler so we need to say connection handler handler equals new connection handler and we pass the client here and here we pass or we add the handler so in order to be able to send something to the client via the handler we need to implement a function here which is just going to send a message so it's going to be a public void send message with string message as a parameter there you go and we're going to just say out dot print line message nothing too complicated here and in order to broadcast now to all the different clients that are connected all we need to do is we need to implement a broadcast function so public void brought cast and we want to broadcast a certain message and this message uh for this we're going to say four connection handler ch in connections so this is for each loop um for each of those we're going to say if it's not null because it can be null for some reason maybe what we're going to do is we're going to call ch dot send message with the message uh as simple as that and essentially what we want to do is want to immediately broadcast that this nickname joint now so join the chat like that and now we want to do is we want for this particular client we want to always have a loop that asks for new messages so we're going to say string the message that we get from the client is going to be null by default and then we're going to say while the message which is in dot readline while this whole thing is not null we're going to process this message so we're going to say if the message um we want to implement a command here so if the message starts with certain commands so for example we can say slash nick in order to change the nickname if the message starts with slash nick and a space then we're going to to do handle nickname then else if for example message dot starts with and then slash quit then we're going to allow the clients to quit and otherwise if there is no command or no known command we're just gonna broadcast the message immediately to all other uh connected clients and for that all we need to do is we need to say broadcast nickname colon and the message so that is the simple thing here so for the nickname all we need to do is we need to get the message so for this we're going to get a string array uh we're going to split the message so the message split is going to be message dot split on the white space with a maximum of two so everything after the white space is going to be a nickname and if the message split has a length of two split dot length equals two i'm going to say that the nickname equals message split index one so the second part of the split because the first one is going to be the slash nick um and before we do that though we're going to broadcast that the nickname is being changed so we're going before the nickname is changed we're going to say nickname renamed themselves to and then message split one and of course we can also do the same thing with system out print line not south come on there you go and then we also get the server lock message and for the uh to the client we want to also say that they changed the name successfully so we want to say nickname or let's go with successfully changed nickname to nickname like that all right um and of course otherwise if the length is not equal to two we're going to say that no nickname was provided so out print line no nickname provided now for quit we're going to call the shutdown function that we don't have yet so we want to have a function that shuts down the server or individual client connection so we're going to have actually uh by the way i think we should initialize the array list here before we do anything else so public server is going to say connections equals new arraylist like that and here we have the connections at so the shutdown function is going to be here it's basically just going to shut down the whole thing um and all we want to do is we actually want to [Music] what do we actually do do we close the server socket because then we would have to define it up there right we should close the server socket though maybe we should make it private so maybe we should or actually a local attribute server socket server like that and then we're going to just assign this here and the rest can be closed one level below that so we can say if not server dot is closed we're going to say server.close uh before that we're actually not before that what we're going to also do is we're going um we need to run this in a while loop by the way so we need to say while not done because we need to always accept connections so we're going to have while not done do that and done is going to be a boolean private boolean done and we're going to set done to true here and we're going to set done to false when we initialize and then we're going to also close the server of course this is going to throw an exception maybe so we need to catch it but in this case i think we cannot really do anything about it anymore so if an exception is thrown here we're just going to ignore it uh you can also say cannot handle because then again you need to uh you need to handle it again and again and again and it's not gonna go anywhere so we shut down the server like that and what we also want to do is want to say for connection handler ch in connections we want to call the shutdown function for each individual connection we don't have this function yet so we're going to go down here and we're going to implement it we're going to say public avoid shutdown and we're going to say if not client dot is closed client dot close we're going to before we do that close also the streams so in dot close out.close and do we have something else here [Music] don't think so let me just see in my prepared code if i missed something no this should work so we need of course to surround it again with try catch catch io exception e and again ignore this exception if it happens now i don't claim that this is the best uh and most clean best practice way to do it but we're going to do it like that for now so if an exception is thrown here we're going to just shut down and if an exception is thrown here we're going to also shut down now when we quit we also want to shut down but we also want to say that the client leaves the server so we're going to broadcast before that that nickname uh left the chat all right so that should be most of that now what we didn't do yet is we didn't run the individual threats so now all these handlers need to be ran in a thread pool a thread pull is basically a number of threads that can be reused all the time so we don't need to run a new thread and close uh like we don't need to create a new specific thread in order to run a handler because we have a lot of different client connections then they disconnect again whereas the server is running in one thread all the time uh the client connections are short lived oftentimes because of that we're going to use a thread pool and we're going to define it locally here so we're going to say private execution service or execute a service it's going to be our thread pool and we're going to uh initialize it here so pool is going to be new or actually it's going to be executor dot executers dot new cached thread pull and we need to import this again there you go and every time we add a new connection we want to say pool dot execute the handler which is going to run the run function all right i think that this is actually all of it when it comes to the server i think uh we're done let me just see if i forgot anything no i have this i have this uh did we set done to true [Music] yeah so i think that's it of course the only thing that we need to do now in the end here is we need to also call the main function so we're going to have um public static void main string array arguments and here we're going to say that the server is going to be a new server and we're going to run this server which again is going to run a connection handler for each connection all right so let's just see if we can run this then we're going to continue with the client so i'm going to run the server now and see if we get any exceptions right away it's going to take some time you can also run this via the command line by the way by just calling java c for compilation and then java class name uh it it is running so seems to work let's go and create the client so client.java and the client is going to be quite simple here we just need two threads one thread is going to be the one that receives all the uh messages from the server and the other one is going to receive our console line input so we're going to enter the messages in the cli this client is also going to implement runnable um and we're going to have here a client socket so not a server socket first of all let's implement the run method and what we're going to do here is we're going to have again try catch io exception e by the way i think one thing that we can change about the server is that the server should shut down no matter which exception is thrown like that because i o exception obviously extends from uh the generic exception so what we're going to do here first of all we're going to say handle here so to do handle and in the try block we're basically going to create socket client equals new socket and here we pass the ip address in this case since we're running it locally it's going to be localhost with the port 9999 and of course if you connect to someone else's server you need to pass their public ip address if it's locally in the local area network you can also pass a private ip address if you're running this on your own computer you can pass localhost which is this one so then again we say out equals new or actually we need to define them here as local attributes first so we're going to have the private socket client because again we're going to have an inner class which is going to handle the inputs so we need this class to be able to access these attributes private buffered reader is going to be in and private print writer is going to be out so out is going to be new print writer client dot get output stream and true for auto flush and in equals new buffered reader new input stream reader client get input stream uh we need to import this okay thanks for the alarm um so we need to import this as well and then what we do is we create the inner class the input handler so class input handler um is going to implement runnable as well and all we need to do in the input handler is we need to constantly ask for new console line inputs so essentially we also have a run function and we're going to again say try as always catch the i o exception and handle it in some way and in the try block we're going to do is we're going to say the buffered reader in reader or we can maybe call it input reader let's call it in reader it's going to be a new buffered reader with a new input stream reader but this time we're going to pass system [Music] dot in so we're going to pass the command line input which means that we're going to be able to do this ourselves when we call readline we're going to be asked to input something and here we're going to say while not done we need to add done again uh to these variables so private do we actually need to add it there i mean we can also add it in the inner class i think but then we cannot shut down from the outside so let's do it here boolean done um [Music] and while not done what we're going to do is we're going to ask for user input so we're going to say if um we're going to say no we're going to say string message equals in reader dot read line and if the message dot equals actually slash quit if this is the case we're going to perform a shutdown so we're going to close the input reader or the in reader and we're going to call a shutdown function that does not exist yet uh and it's not going to exist inside of the handler it's going to exist outside so it's going to exist here we're just going to call the uh the outer class shutdown function so public void shutdown and we're going to do all sorts of things here so we're going to first of all set done to true [Music] we're going to say try to close [Music] come on the input stream here so or the uh the buffer reader then also the print writer and then if not client dot is closed then we're going to also close the client and of course want to catch the exception here but at the end of the day we cannot really do anything about it so we're going to ignore it at this point um yeah so that is if we pass quit otherwise all we need to do is we need to just send the message to the server which is then going to broadcast which will then broadcast a message so we're going to say out dot print line message remember that the out is the stream that we get from the client so this is actually sent to the server i think that's it for the input handler if something happens we need to shut down and inside of the client where are we now we need to also uh create a thread for this one so we're going to say input handler in handler is going to be a new input handler and then we're going to create a thread this time not a thread pull because the input handler is one input handler so thread t equals new thread we pass sorry we pass the input handler here and we say t dot start start is important because run uh doesn't open a separate thread as far as i know start does so after that we're going to then also have an in message here and then we're going to say again while in message which is essentially just in dot read line while this thing is not null we're going to just system out print line it there you go in message and i think that's it of course here we also shut down and if i didn't make any mistakes here this should actually be it this should be this client and the server so let's run the server first and let's see if it works with one client and then we're going to use a command line to run multiple clients so the server should work without a problem now let's right click and oh we don't have a main function we don't have a main function so let's go down here and create a main function and say client client is new client client run now we can run this and hopefully it will connect without exceptions to the server and now i can choose a nickname let's say neural nine neural nine join to chat neural nine connected hey neural nine hey all right so let's close this client now and um let's also close the server now when we run the client let me actually run it one more time you can see the command which is executed now i got an exception because the server is not up um but you can see that this is the command basically we have the java command uh some path and here the important thing is that we specify the class path which is the path uh to the app and then uh we also need to pass uh the class name or if you use a package so if you have packages also the package dot class name uh this is important because we need to run this in the command line so we're going to open up cmd now and i'm going to navigate first to my python directory then back one to my java directory um and then we're going to navigate to neural nine to the chat app and then to the source directory there you go here you have the client java i'm going to do it one more time because i need two chats so java neural nine chat app source and now i'm going to have one to the left one to the right and in here what we're going to do since they're already no they're actually not compiled so what we need to do first is we need to say java c for the compilation and we need to pass class i think class not class client dot java this is going to compile it so if i run ls or deer you can see that i now have client class and client input handler class and now i can run this by saying java i think client will not be enough oh it is actually okay so if you have a package name though you need to provide the class path as well uh but all we need to do now is we need to run java here and java there and we need to run the server first so we don't get an exception and then we should see that all of this works so server is running let's go ahead and run the client here let's run the client java client here as well here i'm going to connect with a neural nine here i'm going to connect with um florian and now i can just say hello i can say hi what is up not much how about you whatever and now i'm going to change the nickname from neural nine to um so i'm going to say nick your favorite youtuber i hope that's right there you go now you can see here neural nine and this guy sees that as well neural nine renamed themselves to your favorite youtuber successfully changed nickname in the server lock you can also see that this happens and now i can just go ahead and say hey and you can see that i now have a new nickname i can now also say slash quit and this should quit the application i'm not sure if it did work but i mean it's still running so let's see where is this actually when i go to the client when i go to quit i have in reader close shut down and this should actually shut down everything so i'm not sure why it's still running because the in is closed out is closed the client is closed the in reader is closed so i'm not sure what's still running to be honest actually everything oh did i set done yeah i said also done to true so i think if i run this in intellij actually it's going to quit i'm not sure why it's not happening in the command line i got an exception now null pointer exception client maybe i have to also close the threat or something i'm not sure uh so let's see if it works here i'm going to call myself hey i'm going to quit right away okay it doesn't seem to work but it worked in the preparation so i think i forgot something let me just see um i think one thing that we should definitely do at least oh the client socket oh this is the problem i'm defining the client socket here but i'm not um using that so i need to remove the socket here so i actually assigned to this socket and now it should work at least i think so and one thing that we also need to do here in the shutdown is we need to shut down or we should shut down the pool so we should say pool.shutdown because that means it will not accept any more uh requests so let's run the server again let's go to the clients again run the clients neural nine florian let's change the nick to bob hey a and now slash quit slash quit okay still doesn't work though does it now maybe it works in intellij now let's connect with a client let's run this test hey quit no still doesn't work okay so let's see what i have in my prepared code i said done to true in close out close i think i do this as well in a client here so in close out closed if client is closed uh if not client is closed close it that's actually all i do and i also close the uh the input handler so i think that when i when i close the server this should actually also close the client connection or was it closed already maybe it just takes some time but it gets this null pointer exception and client shutdown it tries to shut down something that doesn't exist or maybe no this cannot be the reason okay but all in all it seems to work i need to see if i find a fix if i find a fix i'll let you know but all in all the chat works there's just something running in the background or at least terminating too late uh but yeah that's how you build a simple chat simple tcp chat room in java all right i think i found a mistake the problem is that we're not sending the quit command to the server so we need to also say out print line and slash quit or actually we can just send a message here because it equals quit uh because remember in the server we have a branch that handles the slash quit command and if we don't send the actual message if we just shut down then we're not going to trigger this so we need to also send this and one more thing that i realized is that i always run the same thing without compiling it so i need to again say java c client uh java client.java and then we can run it so first of all let's run the server server run and then we can go with the clients as well so java client and java client now neural nine and florian hey and then slash quit florian left the chat and you can see that it's quit there you go so now it works finally uh this was the problem we were not sending the command the actual commands to the server and also while testing we didn't compile uh what we changed so that's it for today's video hope you enjoyed and hope you learned something if so let me know by hitting a like button and leaving a comment in the comment section down below and of course don't forget to subscribe to this channel and hit the notification bell to not miss a single future video for free other than that thank you so much for watching see you next video and bye [Music] you
Original Description
In this video we build a simple TCP chat room in Java.
◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾
📚 Programming Books & Merch 📚
🐍 The Python Bible Book: https://www.neuralnine.com/books/
💻 The Algorithm Bible Book: https://www.neuralnine.com/books/
👕 Programming Merch: https://www.neuralnine.com/shop
🌐 Social Media & Contact 🌐
📱 Website: https://www.neuralnine.com/
📷 Instagram: https://www.instagram.com/neuralnine
🐦 Twitter: https://twitter.com/neuralnine
🤵 LinkedIn: https://www.linkedin.com/company/neuralnine/
📁 GitHub: https://github.com/NeuralNine
🎙 Discord: https://discord.gg/JU4xr8U3dm
🎵 Outro Music From: https://www.bensound.com/
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from NeuralNine · NeuralNine · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Visualizing Stock Data With Candlestick Charts in Python
NeuralNine
Python Beginner Tutorial #1 - Installation and First Program
NeuralNine
Python Beginner Tutorial #2 - Variables and Data Types
NeuralNine
Python Beginner Tutorial #3 - Operators and User Input
NeuralNine
Python Beginner Tutorial #4 - If Statements and Conditions
NeuralNine
Python Beginner Tutorial #5 - Loops
NeuralNine
Python Beginner Tutorial #6 - Sequences and Collections
NeuralNine
Python Beginner Tutorial #7 - Functions
NeuralNine
Python Beginner Tutorial #8 - Exception Handling
NeuralNine
Python Beginner Tutorial #9 - File Operations
NeuralNine
Python Beginner Tutorial #10 - String Functions
NeuralNine
Python Intermediate Tutorial #1 - Classes and Objects
NeuralNine
Python Intermediate Tutorial #2 - Inheritance
NeuralNine
Python Intermediate Tutorial #3 - Multithreading
NeuralNine
Python Intermediate Tutorial #4 - Synchronizing Threads
NeuralNine
Python Intermediate Tutorial #5 - Events and Daemon Threads
NeuralNine
Python Intermediate Tutorial #6 - Queues
NeuralNine
Python Intermediate Tutorial #7 - Sockets and Network Programming
NeuralNine
Python Intermediate Tutorial #8 - Database Programming
NeuralNine
Python Intermediate Tutorial #9 - Recursion
NeuralNine
Python Intermediate Tutorial #10 - XML Processing
NeuralNine
Python Intermediate Tutorial #11 - Logging
NeuralNine
Python Data Science Tutorial #1 - Anaconda and PyCharm Setup
NeuralNine
Python Data Science Tutorial #2 - NumPy Arrays
NeuralNine
Python Data Science Tutorial #3 - Numpy Functions
NeuralNine
Python Data Science Tutorial #4 - Plotting Functions With Matplotlib
NeuralNine
Python Data Science Tutorial #5 - Subplots and Multiple Windows
NeuralNine
Python Data Science Tutorial #6 - Matplotlib Styling
NeuralNine
Python Data Science Tutorial #7 - Bar Charts with Matplotlib
NeuralNine
Python Data Science Tutorial #8 - Pie Charts with Matplotlib
NeuralNine
Python Data Science Tutorial #9 - Plotting Histograms with Matplotlib
NeuralNine
Python Data Science Tutorial #10 - Scatter Plots with Matplotlib
NeuralNine
Python Data Science Tutorial #11 - 3D Plotting with Matplotlib
NeuralNine
Python Data Science Tutorial #12 - Pandas Series
NeuralNine
Python Data Science Tutorial #13 - Pandas Data Frames
NeuralNine
Python Data Science Tutorial #14 - Pandas Statistics
NeuralNine
Python Data Science Tutorial #15 - Pandas Sorting and Functions
NeuralNine
Python Data Science Tutorial #16 - Pandas Merging Data Frames
NeuralNine
Python Data Science Tutorial #17 - Pandas Queries
NeuralNine
Python Machine Learning Tutorial #1 - What is Machine Learning?
NeuralNine
Python Machine Learning Tutorial #2 - Linear Regression
NeuralNine
Python Machine Learning Tutorial #3 - K-Nearest Neighbors Classification
NeuralNine
Python Machine Learning #4 - Support Vector Machines
NeuralNine
Python Machine Learning Tutorial #5 - Decision Trees and Random Forest Classification
NeuralNine
Python Machine Learning Tutorial #6 - K-Means Clustering
NeuralNine
Python Machine Learning Tutorial #7 - Neural Networks
NeuralNine
Python Machine Learning Tutorial #8 - Handwritten Digit Recognition with Tensorflow
NeuralNine
Generating Poetic Texts with Recurrent Neural Networks in Python
NeuralNine
Stock Portfolio Visualization with Matplotlib in Python
NeuralNine
Analyzing Coronavirus with Python (COVID-19)
NeuralNine
Making Text Images Readable Again with Python and OpenCV
NeuralNine
Neural Networks Simply Explained (Theory)
NeuralNine
Motion Filtering with OpenCV in Python
NeuralNine
Top 5 Programming Languages To Learn in 2020
NeuralNine
Simple TCP Chat Room in Python
NeuralNine
Image Classification with Neural Networks in Python
NeuralNine
Edge Detection with OpenCV in Python
NeuralNine
S&P 500 Web Scraping with Python
NeuralNine
Simple Sentiment Text Analysis in Python
NeuralNine
Introduction - Algorithms & Data Structures #1
NeuralNine
More on: AI Pair Programming
View skill →Related Reads
📰
📰
📰
📰
AI CLI Tools Are Eating Each Other's Lunch
Dev.to · Tracepilot
Loop Engineering: The Skill That Just Made Your AI Workflow Obsolete
Medium · Machine Learning
We built a real-time Pokémon TCG AR overlay for live streams and open-sourced everything
Medium · Deep Learning
I tested the new Claude Desktop on Linux - here's how it compares to rival apps
ZDNet
🎓
Tutor Explanation
DeepCamp AI