A while back I had interviewed with a company that was looking to hire a full-stack developer with experience building Android apps and who knew just enough NodeJS to work on their realtime socket-based backend code. After speaking on the phone the company and I came to the conclusion that they would judge my application on how well I performed on the take-home coding assignment which was to develop a real-time whiteboard/drawing application together with an accompanying Android app.
Unfortunately I never got that job but the results of the take-home assignment I coded together one evening did impress a few of the devs on their team. Anyways, lets step through the server code.
Our whiteboard app will need the following from a server perspective.
The ability for multiple users to connect in realtime
A way for users to draw on the whiteboard using their mouse
A method for ‘clearing’ the whiteboard to start fresh
Those were the conditions given to me during by the company I was interviewing for and as an additional requirement the whiteboard app had to serve both web and mobile clients simultaneously. Given that we want to write our application in NodeJS we will need to choose the following libraries in order to build out a robust functioning application in the shortest time span.
1) A reliable web-framework
2) An easy to use web-socket implementation
At the time those requirements basically boiled down to choosing the Express web framework for NodeJS and the Socket.IO library for quickly spinning up a real-time bi-directional event based web service.
Install Node.js on your development machine before you begin.
Create a new directory and call it whiteboard-server.
Now run the npm command to initialize a new project.
Just press enter for all of the questions you will be prompted with. Once that is done we’ll add dependencies to our
package.json file. From within the project directory
whiteboard-server run the following three commands.
At this moment make sure your
package.json file resembles mine.
Finally lets write the server component; add a new file call it
index.js; we begin by importing a few libraries and setting the default PORT number. Later when we run our server we can connect to it on
Next, in order to define our whiteboard we need to choose a representative data structure. In our case we want to imagine that each drawable portion of our whiteboard is a tiny square representing say an index in a 2D array. If the value ofthe 2D array at any co-ordinate pair is
false that means there is no ink. Thus our whiteboard will be initialized as a 2D array where every element of our array is false;
We have our function called
initBoard which we can now store as a variable to represent the initial state of our whiteboard. I choose to call it paintBoard in order to distinguish it from the title of the article.
Remember earlier when we defined our
Express server as
var app = require('express')();. Lets define the port, attach the log format middleware and set a single endpoint for our clients to connect to. The singular endpoint
/ located at the root directory of our web app will return the file
index.html which will render the interactive web-socket based UI for clients connecting over their web browsers.
Don’t worry about the contents of index.html yet; we will be covering the web UI in part II of this series
So far we have setup our web server, defined the whiteboard as a matrix of boolean elements and imported the necessary libraries to run our app but the last piece of the puzzle is the actual socket code.
Surprisingly we aren’t building the most complex whiteboard application so our socket code will broken up into the following
Event handlers(also known as emitters)
connection When a new client connects
paint When a client sends a paint event
debug During testing if we want to verify our server-client connection
clear When the client clears all ink from the whiteboard
disconnect self explanatory
newClient Server emits that a new connection has been made
paint Server lets everyone know when a client has drawn
debug Acknowledges the clients debug event
clear Server lets clients know that the board has been cleared
Socket.io has a very conscise API, to begin we need to wrap our event calls in a
io block defined and given a socket instance lets go ahead and write our events. The very first event will trigger immediately after the client enters the
connection block so we should send them the current state of the paint board.
Next we are going to react or listen and take action on the various listeners we outlined earlier in the article. For instance when the server handles a
paint event it should paint the co-ordinates and let every client know the board has been drawn on.
When a client sends a debug message we simply want to echo it back.
clear we need to reset the paintBoard and immediately send off a signal to the client so they know to clear their board as well.
Finnally we should print a message for our server to acknowledge that a client has disconnected.
Now that we have our server code in place let listen for new clients and together with the web UI we’ll cover in part II we can start running our application.