Make A Real-Time Talk Room Using Knot Webkit, and MEAN – Scotch
Make A Real-Time Talk Room Using Knot Webkit, Socket.io, and MEAN
Overview
Development folks work tirelessly to make building programs as effortless as possible. The JavaScript, Web and Mobile app developers communities enlargened drastically since Knot and Cordova were introduced. Developers who had web design abilities could, with less effort, roll out a server using JavaScript for their applications, through the help of Knot.js.
Mobile paramours can with the help of Cordova now build rich hybrid apps using just JavaScript. Today, albeit it is old news, I am excited to share the capability of using JavaScript to build desktop standalone applications.
Knot Webkit normally written "node-webkit" or "NW.js" is an app runtime based on Knot.js and Chromium and enables us to develop OS native apps using just HTML, CSS and JavaScript.
Simply put, Knot Webkit just helps you utilize your skill as a web developer to build native application that runs cosily on Mac, Windows and Linux with just a grunt/gulp (if preferred) build instruction.
This article concentrates a lot more on using Knot Webkit, but in order to make things more interesting, we will be including other amazing solutions and they will include:
- Socket.io A realtime library for Knot.js
- Angular Material: Angular’s implementation of Google’s Material Design
- MEAN: MEAN is just a concept of combining the features of Mongo, Express, Angular and Knot to build powerful apps
Furthermore, the application has three sections:
The web section will not be covered here, but it will serve as a test platform but don’t worry, the code will be provided.
Prerequisites
Level: Intermediate (Skill of MEAN is required)
Installation
We need to grab node-webkit and every other dependencies for our application. Fortunately, there are frameworks that make workflow effortless and we will be using one of them to scaffold our application and concentrate more on the implementation.
Yo and Slush are popular generators and any of these will work. I am going to be using Slush, but feel free to use Yo if you choose to. To install Slush make sure you have knot and npm installed and run
The guideline will install the following globally on our system.
- slush: a scaffolding implement
- slush-wean : the generator for Knot Webkit
- gulp: our task runner
- bower: for frontend dependencies
Just like YO, make your directory and scaffold your app using:
Running the below directive will give us a glance of what we have been waiting for:
The picture shows our app loading. The author of the generator was generous enough to provide a nice template with elementary loading animation. To look cooler, I substituted the loading text with Scotch’s logo.
If you are not convenient with Slush automating things you can head right to knot webkit on GitHub or see the beginners movie series.
Now that we have setup our app, however empty, we will give it a break and prepare our server now.
The Server
The server basically consists of our model, routes and socket events. We will keep it as ordinary as possible and you can feel free to extend the app as instructed at the end of the article.
Directory Structure
Setup a folder in your PC at your beloved directory, but make sure the folder content looks like the below:
Dependencies
In the package.json file located on your root directory, create a JSON file to describe your application and include the application’s dependencies.
That will do. It is just a minimal setup and we are keeping things elementary and brief. Run npm install on the directory root to install the specified dependencies.
Commencing Our Server Setup
Huuugh. It is time to get our arms dirty! The very first thing is to setup global variables in server.js which will hold the applications dependencies that are already installed.
Ok, I didn’t keep to my word. The variables are not only holding the dependencies, but some are configuring it for use.
To serve static files, express exposes a method to help configure the static files folder. It is ordinary:
Next up is to create a connection to our database. I am working with a local Mongo DB which obviously is optional as you can find it’s hosted by Mongo databases. Mongoose is a knot module that exposes amazing API which makes working with Mongo DB a lot much lighter.
With Mongoose we can now create our database schema and model. We also need to permit CORS in the application as we will be accessing it from a different domain.
Our server will have three routes in it. A route to serve the index file, another to setup talk data and the last to serve talk messages filtered by room names:
The very first route I believe is effortless enough. It will just send our index.html file to our users.
The 2nd /setup is meant to be hit just once and at the initial launch of the application. It is optional if you don’t need some test data. It basically creates an array of talk messages (which matches the schema), loops through them and inserts them into the database.
The third route /msg is responsible for fetching talk history filtered with room names and returned as an array of JSON objects.
The most significant part of our server is the realtime logic. Keeping in mind that we are working towards producing a elementary application, our logic will be comprehensively minimal. Sequentially, we need to:
- Know when our application is launched
- Send all the available rooms on connection
- Listen for a user to connect and assign him/her to a default room
- Listen for when he/she switches room
- And, eventually, listen for a fresh message and only send the message to those in the room at which it was created
Then the traditional server commence:
Pack the index.html with any HTML that suites you and run knot server.js . localhost:2015 will give you the content of your HTML.
The Knot Webkit Client
Time to dig up what we left to create our server which is running presently. This section is fairly effortless as it just requires your everyday skill of HTML, CSS, JS and Angular.
Directory Structure
We don’t need to create any! I guess that was the inspiration of generators. The very first file you might want to inspect is the package.json .
Knot Webkit requires, basically, two major files to run:
- an entry point ( index.html )
- a package.json to tell it where the entry point is located
package.json has the basic content we are used to, except that it’s main is the location of the index.html , and it has a set of configuration under "window": from which we define all the properties of the app’s window including icons, sizes, toolbar, framework, etc.
Dependencies
Unlike the server, we will be using bower to explosion our dependencies as it is a client application. Update your bower.json dependencies to:
For a shortcut, just run the following instruction:
Now that we have our frontend dependencies, we can update our views/index.ejs to:
We included all our dependencies and custom-made files (app.css and app.js). Things to note:
- We are using angular material and it’s directives are making our code look like "HTML 6".
- We are looping through our messages scope using ng-repeat and rendering it’s values to the browser
- A directive which we shall see later helps us to send the message when the come in key is pressed
- On init , the user is asked for a preferred username
- There is an Angular library that is included to help working with socket.io in Angular lighter.
The Application
The main part of this section is the app.js file. It creates services to interact with the Knot Webkit GUI, a directive to treat the come in keypress and the controllers (main and dialog).
Next up, we create three angular services. The very first service helps us get that Knot Webkit GUI object, the 2nd comebacks it’s Window property and the third bootstraps Socket.io with the base url.
The above snippet is one of my favorites ever since I have been using Angular. It ties an event to the inject key, which thereby an event can be triggered when the key is pressed.
Eventually, with the app.js is the almighty controller. We need to break things down to ease understanding as we did in our server.js . The controller is expected to:
- Create a list of window menus from using the rooms emitted from the server.
- The user on joining is expected to provided his/her username.
- Listen for a fresh message from the server.
- Notify the server of fresh messages when they are created by typing and hitting the inject key.
Create a List of Rooms
With our objectives defined let us code:
That is our controller’s skeleton with all of it dependencies. As you can see, it has four internal comments which is serving as a placeholder for our codes as defined in the objectives. So let’s pick on the menu.
We simply created instances of the menu and appended some menu (Rooms and Exit) to it. The rooms menu is expected to serve as a drop-down and so we have to ask the server for available rooms and append it to the rooms menu:
The above code with the help of a function, loops through an array of rooms when they are available from the server and then append them to the rooms menu. With that, Objective #1 is finished.
Asking for a Username
Our 2nd objective is to ask the user for username using angular material modal.
As specified in the html, on init, the usernameModal is called. It uses the mdDialog service to get username of a joining user and if that is successful it will assign the username entered to a strapping scope, notify the server about that activity and then shove the user to the default (GENERAL) room. If it is not successful we close the app. Objective #Two finished!
Listening For Messages
The third, and the last, objective is plain. #Three just listens for messages and if any thrust it to the array of existing messages and #Four notifies the server of fresh messages when they are created. At the end of app.js , we create a function to serve as the controller for the Modal:
CSS and Animation
To fix some ugly looks, update the app.css.
Note the last style. We are using ngAnimate and animate.css to create a pretty animation for our messages.
I already wrote on how you can play with this concept here.
Closing Up
I can guess what you are worried about after looking at the picture! The address bar, right? This is were the window configuration in the package.json comes in. Just switch "toolbar": true to "toolbar": false .
I also set my icon to "icon": "app/public/img/scotch.png" to switch the window icon to Scotch logo. We can also add notification once there is a fresh message:
And even more joy.
Testing
I suggest you test the application by downloading the web client from Git Hub. Run the server, then the web client and then the app. Begin sending messages from both the app and the web client and see them show up in realtime if you are sending in the same room.
The demo server is on here and the web client here.
Go Further
If you want to challenge yourself further, you can attempt to add the following to our app
- Authentication with Facebook.
- Admin section to update rooms.
- Use a real user avatar.
- Deploy the app using gulp deploy –<> eg: gulp deploy –mac . * etc.
Conclusion
I am glad we made it to the end. Knot Webkit is an amazing concept. Join the community and make building apps lighter. Hope you had a lot of scotch today and that I made someone smile.