Building a simple IRC with Rust
I was recently invited as tech speaker to sahyadri engineering college to conduct a workshop on rustlang and to make use of AWS if possible.
And I then began to think of right use case that can show the capablity of Rustlang along with its suitability with AWS. Initial thoughts are to make use of AWS lambda and trigger a rustlang function, but felt that it is not enough and useful to the students straigtaway. Suddenly struck to my mind, is to build an IRC server using rocket web framework for both client and the server.
Why IRC?
Unlike stackoverflow, an IRC(Internet Relay Chat) is a realtime group chat platform where anyone could pose a question or start a discussion and instantly get helped by the community. On the bright side, It is one kind of knowledge sharing platform where people can collaborate and learn from each other.
There are two parts for an IRC,
one is the server which holds metadata of the clients registered to it(kind of nameserver) and also takes responsibility for broadcasting the messages.
Second is the client side, where it stores the session id and also message history.
Infra Setup:
- An AWS account with some credits, as we will be using a non-free tier centos VM.
- Postman client.
- SSH client (putty for windows).
APIs implemented
Server side APIs:
=> GET /
=> GET /register/<name>/<ip>
=> POST /broadcast
=> GET /logout/<id>/<name>/<ip>
Client side APIs:
=> GET /
=> GET /<user>
=> GET /register/<name>
=> GET /send/<message>
=> GET /receive/<user_name>/<message>/<time>
=> GET /get/messages/<count>
=> GET /logout
STEPS:
1. Create a VM in AWS EC2 console:
- Sign in to AWS console at https://aws.amazon.com/console/.
- Select EC2 after clicking on services tab on the top
- Click on launch instance
- Choose an AMI after selecting Community AMIs tab and selecting centos from the operating systems list populated on the left side tab.
- Select the CentOS Linux 7 x86_64 AMI
- Choose a t2.small instance type
- Click on next: Configure instance details button available in the bottom
- On the next screen, select “enable” option for “Auto assign public IP” shown below
- Now directly skip to configure security groups tab and a security rule for allowing http traffic, for now make the source as anywhere (You could whitelist a specific static/public there, if you have one)
- Click on review and launch
- Click on launch and you see the screen to create a key pair and give a name to it and click on download for the key pair. You can find the key pair in your download location of your browser.
- Launch instances and you will be back to ec2 dashboard page where you can find your VM. It will take time to actually be ready, wait until the instance state column says “running”.
Connecting to the VM
- Once the instance is running, select the instance and click on “connect” button above.
- In the above screenshot, step3 talks about changing the permissions of the key pair previously downloaded and the command mentioned in example section can be used to connect to your VM instance.
- In the download folder where your previously downloaded
sample_key_pair.pem
is located, run the following command from terminal to reduce the permissions.chmod 400 sample_key_pair.pem
- At the same location, run the command to connect to VM instance through SSH.
ssh -i "sample_key_pair.pem" root@ec2-13-126-180-28.ap-south-1.compute.amazonaws.com
If this command doesn’t work for you, try this:ssh -i "sample_key_pair.pem" centos@ec2-13-126-180-28.ap-south-1.compute.amazonaws.com
- From the above SSH command, you can figure out public IP of the instance as 13.126.180.28, make a note of it.
2. Installing essential packages
- After login, change to root to install some packages typing
sudo su && cd
- Install packages
yum -y install git docker vim
- Start the docker daemon with
service docker start
- Clone the repo
git clone https://github.com/krishnakumar4a4/rust-irc.git
- A folder rust-irc will be created locally which has both client and server.
3. Running the irc server on the machine
cd rust-irc/rust-irc-server/
docker build -t rust-irc-server:1.0 .
docker run -it --name rust-irc-server -p 80:80 -d rust-irc-server:1.0
- Check the container by running
docker ps
- Check the logs using
docker logs -f rust-irc-server
Note: You will see huge log printing the terms downloading and compiling, please wait all of them finishes and give the message:🚀 Rocket has launched from http://0.0.0.0:80
- Now the server is ready.
- Make a note of the server public IP address mentioned in previous step 1
Repeat the steps 1 & 2 to create one more VM for the Client
4. Running the IRC client on the machine
cd rust-irc/rust-irc/
- Edit the conf.ini file with server public IP address and client public IP address as you have identified at the end of step 1.
docker build -t rust-irc:1.0 .
docker run -it --name rust-irc -p 80:80 -d rust-irc:1.0
- Check the container by running
docker ps
- Check the logs using
docker logs -f rust-irc
Note: You will see huge log printing the terms downloading and compiling, please wait all of them finishes and give the message:🚀 Rocket has launched from http://0.0.0.0:80
- Now the server is ready.
- Make a note of the client public IP address mentioned in previous step 1. This IP address should be used for postman.
5. Checking with postman client
- Register the client with a name and you should see “registered u” as response indicating successful registration.
- Send message, it is asynchronous and hence you see no response if successful
- Client has to poll for messages from the server, Here is how you get the last message
- Since you are the only client connected as of now, you see your own message, If you publish your server public IP address to your friends and ask them to use this in their client configuration, you will see their messages too.
- Finally, once you register with a name, you will not be able to register with the same name, until you logout.
Next steps:
- Building a nice web UI replacing postman client.
- Use websockets for client to server connection for real time status, connection and session management.
- Use cache for session management on the server side instead of hashmap.
- Enhance the existing client and server APIs, some of them can be rewritten to POST methods, instead of GET.
- Build more APIs as required for the UI.
Code:
- Available on github at https://github.com/krishnakumar4a4/rust-irc
- Star it if you like it. Open to contributions all the time.
- Reach me out at @KrishnaKumarT36 on twitter or on linkedIn .
Disclaimer:
Project doesn’t implement the real IRC protocol, it simply uses REST to emulate this behavior.