Skip to content

JaanP1/chatroom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chatroom Application

A lightweight and easy to use chatroom application made for quick communications between people. No hassle, no account needed, simply create a room and share the link with friends to message and share images. Users have the option to save messages and protecting rooms with a password. It was built with HTML, CSS, Javascript and NodeJS using socket.io API. Go to jaanparekh.com to test the application, use multiple tabs to test features (the application will treat each tab as a different user).

Features

  • Nicknames
  • Direct private messaging in public rooms
  • "X is typing..."
  • Show a list of online users
  • Dynamically create new rooms
  • Option for saving messages in a room
  • Option to create password protected rooms
  • Notifications
  • Sending, receiving and saving images

How to use

Index Page: image

Here, users have three options. First option is to "Enter General Chat"; it is a general purpose chatroom that is not password protected, messages are not saved and private messaging is allowed.

Second option is "Enter Existing Room", upon clicking it the user will get a field to enter an already existing chatroom.

Third option is "Create New Room", upon clicking it the user will have several options for the new room, they can make it password protected and/or save messages.

Note that chatroom names are unique. Users can also enter a chatroom directly by entering its name in the path after the domain name. If the user enters a path that does not exist, a room that is identical to the general room will be created.

Once a room is entered the user will be asked to input a nickname. Upon entry the user will see a list of online users in the top left corner and a private message button on the top right. See below: image

Clicking the private message button will show a list of users that are currently online in the chat and clicking on one of the users in the list will activate the private messaging mode. Private messaging mode will make the messages appear in red and will let the sender and receiver know who sent it and who it was for.

Implementation of some key features

"User is typing" notifications

What does it do?

![image](https://user-images.githubusercontent.com/42306776/185996147-f5bf137b-1ac4-463a-8fc3-dc49e21d6d0d.png) This feature shows every user that is currently typing a message in the room. Once they send or stop typing for a few seconds, their names dissappear. This alert is not displayed when the user is in private messaging mode.

Initial Implementation

The client sent the server a "user is typing" message with every keystroke. The server sent the name of the typer to all the other clients connected to the same room, where the typers name would be displayed.

Problem with this Implementation

The main problem was sending an alert with each key stroke. It was unnecessary and it can reduce the performance of the application from all the alerts sent between the clients and the servers. Constantly sending and receiving alerts for each keystroke from every single user can reduce the battery life of device for the client as well.

Solution

A user is either in a state of "typing" or "not typing". If we keep track of these states, we can eliminate the need to send an alert with every keystroke, instead sending an alert only when the user changes state. The application keeps a track of the state on the client side, if the user is "not typing" and a keystroke is detected their state is now "typing". If the user is "typing" we start a timer of several seconds. Each keystroke resets the timer. Once the timer runs out they are now "not typing".

Next Steps

The solution can still be improved. Firstly, we can add server side validation to check the changes in the user state. A malicious user can modify the script on the client side to constantly send alerts. Secondly, we can represent users as objects, add a isTyping field and change this value with a method for better code organization. Currently, the "isTyping" state is tracked with a boolean variable.

Designing the database for saving messages and rooms

Design

This project uses a relational database, MySql. There are three tables, chatrooms, messages and images. The chatroom table records chatroom_id (key), chatroom_name (text), is_password_needed (boolean), password (encrypted with bcrypt) and is_saved (boolean). The message table records message_id(key), chatroom_id (the key of the chatroom the message was sent in), sent_by (text), message (text), is_private (boolean), sent_to (text) and is_image (boolean). THe image table records file_name(text), file_type(text), directory(text) and mesage_id(int).

Next Steps

Add a new column for messages called is_image. Create a new table called images with the following columns: add message_id(key), file_name, directory, file_type and message_id (connect messages and images).

Entering and creating chatrooms

Design

The users can type in a room name after the domain and the application will direct them an existing room or it will create a new one with basic features. In detail:
  1. Check if the room exists. If it does not create it.
  2. Get the chatroom_id.
  3. Check if the is_saved field for the chatroom is true.
  4. If is_saved is true, get the last X messages for that chatroom(the messages are connected to chatrooms with chatroom_id column).
  5. Check if password is required for the chatroom.
  6. If it is, redirect user to the login page, else send them to the chatroom.
  7. If the user enter the correct password, send them to the chatroom page.

Next Steps

Reduce database calls by:
  1. Check if the chatroom name is prohibited before any database calls.
  2. Get all chatroom properties in a single call from the database.
  3. Fetch the previous messages after the password is entered correctly to minimize database calls.

Sending, receiving and saving images

How it works

Sending and receiving images were simple. Convert the image into a base64url, send it and then convert to an image on the receivers side. Saving and retrieving on the other hand required more thought. There were three possible implementations for this feature, below I will explain each and my thought process as to why I chose or didn't choose them.
Method 1: Store the images as a BLOB (Binary Large Object) in the database
Not chosen
Advantages: Storing the image inside a database will ensure the integrity of the file (ACID principles).
Disadvantages: Reading and writing large files into a database can cause performance and memory issues.
Verdict: Not chosen due to performance issues and the integrity of the image is not a concern as long as it is visible to the humam eye.
Method 2: Store the images inside the disk and the directory inside the database
Chosen
Advantages: Storing the image inside the disk is cheaper compared to storing in the database in terms of performance and memory.
Disadvantages: It is easier for users to gain access to images they are not supposed to, if you are not careful.
Verdict: Chosen, because of better performance and data of that size is better suited for disk, compared to databases. It is also easy to deny access to users from simply going into the image folders. However, there is another method below that will scale better for a bigger application.
Method 3: Amazon S3
Not chosen

Advantages: Cheap, easy to use and scalable.
Disadvantages: Need to create Amazon Account.
Verdict: Not chosen, due to the fact that I already payed for disk space... Will be the first choice if the application had more users and need for more data storage services.

About

A chatroom application

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published