3 or 4 years ago, I wrote my own in-house messenger. It was a fun project and
I would like to share a few insight on how to build one and what are you required
to learn in order to build one.
Pre-requirement
- Any programming language
- TCP Programming
- Thread
Content
- Concept
- Protocol Design
- Package Length
- Ping Pong
- Group Chat
- File Sharing
- Screen Sharing
- Voice Chat and Web Cam
1. Concept
There are three important components that you need to understand.
- Server: one of the basic role of server is to manage connected clients and relay message from client to client.
- Client: communicate with server and provide interface for user.
- Protocol: a language that server and client are used to understand each other. So if you want to build your own messenger, you will have to design your own protocol.
As you see in our example,
- Anna (client) sent a message "SEND Bluedog I love you" to the server.
- Server interpreted the message and understand that Anna (client) wanted to send "I love you" message to Bluedog (client)
- Server relayed the message to Bluedog (client)
2. Protocol Design
It is impossible for person who only speak French to communicate to person who only speak Russian. It is same for SERVER and CLIENT as well. Both of them must speak the same language. To build messenger, you need to build the language and there is no standard rule on how to build one. It is up to your creativity.
I will give you a simple protocol design as an example so that you will see a bigger picture of what it is.
- SEND [SEND_TO] [MESSAGE]
When client send this message to the server, it means that current client want to send [MESSAGE] to [SEND_TO].
For example: SEND Bluedog I love you.
-
- SEND [SEND_FROM] [MESSAGE]
When client received this message from server, it means that [SEND_FROM] has sent you [MESSAGE].
For example: SEND Anna I love you. It means Anna has sent you "I love you".
-
- LOGIN [USERNAME] [PASSWORD]
Send your username and password to verify who you are to the server.
-
- LOGIN SUCCESS
When client receive this message, it means that client has provided a correct username and password.
-
- LOGIN FAIL
When client receive this message, it means that client has provided a incorrect username and password.
-
.... more and more
3. Package Length
Actually, this one is belonged to Protocol Design, but I will separate this because there are great length of technique that I want to discuss.
Server and client will communicate with each other by stream of bytes. When client send some message to server, server has no idea how long the message really is. For example, when client sends 500 bytes of data to server, server does not know how many messages in that 500 bytes.
- Maybe there are two messages where the first message is 100 bytes and second message is 400 bytes.
- Maybe 500 bytes is exactly one message
- Maybe 500 bytes is only partial of one message. Maybe client hasn't completely send all the data of that received message.
In this section, I will present you with three techniques for you to choose.
3.1: Fixed Size Message
You can set all message to have the same length. For example, all message must be 255 bytes. If you send message that is shorter than 255 bytes, you simply add padding bytes until it is 255 bytes.
Pros:
- Easy to implement
Cons:
- You waste your bandwidth by sending padding bytes.
3.2: Header
Every message start with 1 byte header (if you want to allow longer message, you can have a bigger byte header) that tell how many bytes is the message. 1 byte header allows up to 255 byte of message, 2 byte header allows up 65535 byte of message.
For example: "SEND Bluedog I love you" (23 bytes). You start by sending 1 byte of message including the length of the upcoming message. Then send 23 bytes of "SEND Bluedog I love you" data later.
3.3: Delimited Byte
Another technique is to reserved one byte of value as a delimited. For example, the message is ended when we reach byte with value "\n" (13).
4. Ping Pong
Sometimes, server does not know when one of the connected client has been disconnected. For example: Anna (client) had crashed and unable to start back. Since Anna computer is crashed, it is not possible for client to send notification that Anna has been disconnected. Ping Pong is technique that send to client that has been idled to check if the client is still responding. This is also one part of Protocol Design.
4. Group Chat
Group chat and private chat are the same except that group chat relay to multiple client instead of replay to single client. For example, protocol for send message to group is "GROUPSEND [GROUP_ID] [MESSAGE]". When server received this message, server will check who is inside the group besides the sender, then send to those clients.
5. File Sharing
For file sharing feature, we need to have separate server to deal with it to ensure that if there is anything wrong with file sharing, it does not affect the normal chatting performance. The following is how I implement file sharing between two clients.
(1) Request file server to make a connection and get token that is used to shake hand with another client.
(2) When you got the token, send the token to the another client.
(3) Another client accept the request and file server notify the sender to start sending the content of the file.
(4) Client send data to file server and file server relay the data to another client
6. Screen Sharing
Screen Sharing is a very challenging problem. The simplest implementation is to constantly take screenshot of your screen and send to server. However, it will be very slow because you will send a large size of data continuously. What I do to improve the speed of screen sharing is to:
- Divide the screen into 16 sections. Check if any sections has changed and send it to server.
- I treat mouse cursor as not part of the screenshot because the location of the mouse will be the most frequently changed. I simply send mouse location and mouse icon type.
- Most importantly, separate the chatting and screen sharing server. You cannot use a single socket for chat and screen sharing at the same time.
7. Voice Chat and Web Cam
Reserved. (Hungry, I need to eat, then I will come and write more)