Tute 06: simple Chat app with Web socket - ariffira/node-basic GitHub Wiki

Requirements:

  • node js basic
  • express js
  • javascript and html knowledge
  • npm knowledge
  • client-server concepts

We will create a Chat application using nodejs and template engine. See below pictures

What we will learn:

  • nodejs rest api using express js
  • Websocket using socket.io for both client and server
  • template engine like Handlebarjs

Two side flow of data here as:

  1. Server side is running on Node.js(express backend)
  2. Client side is running on user browser(front end using handlebarjs later we will use reactjs in another tute)

Lets create a folder called chatAPP

Step 01: create package.json file and add below lines:

npm init

Then install express, socket.io and handlebarjs

npm install --save express socket.io express-handlebars

Check your package.json to confirm that all these package installed :)

Step 02: set up server code with app.js file

Create app.js file and add below codes for server:

// this is our chat server
// include all necessary files here
const express = require("express")
const path = require("path")
const app = express()
// include express handlebar module
var exphbs  = require('express-handlebars');

// define port number for server
const SERVER_PORT_NUMBER = 5000

// This is config for render view in `views` folder
// and use handlebars as template engine here
app.set('views', path.join(__dirname, 'views'))

// setting default page layouts which is under views/layouts/index.handlebars and view engine as handlebarjs
app.engine('handlebars', exphbs({defaultLayout: 'index'}));
app.set('view engine', 'handlebars')

// home routes 
app.get('/', (request, response) => {
    response.render('home')
})

app.listen(SERVER_PORT_NUMBER, () => {
    console.log(`My simple Chat App running on port Number ${SERVER_PORT_NUMBER}`)
})

Now create index view which is default layout for creating a single page apps. Create it as: **views/layouts/index.handlebars** and add below html codes there with a {{body}}

{{body}} will contain body content for other pages which will change but default index will be same.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>My Chat App</title>
</head>
<body>
<h1>My Chat App based on Node js</h1>
{{{body}}}

</body>
</html>

inside {{}} of handlebar file we can keep our code, data and information to use. This is called Handlebars expressions. For more detail check here: handlebar expression

lets use nodemon first so our server will restart itself for us:

npm install --save nodemon

and

"server": "nodemon app.js" //in scripts of package.json

then start npm run server

add this line in app.js '/' routes

let pageTitle = "home page" // data to send 
response.render('home', {pageTitle});

Now you can use pageTitle data like this in index file or home file

    <title>{{pageTitle}}</title>

For simplicity and quick design i will use bootstrap to design my chatApp. Lets include and from bootstrap website to your index.handlebars file and then add a NavBar before {{body}} like below structure:

...
<head>
  <link> //all link will be here
</head>
<body>
  <navbar>
    .......... your bootstrap code for default navbar and add your routes and changes here
  </navbar>

{{body}}

<scripts></scripts>// all your scripts before end the body will be here
</body>
...

create a new routes for chatting

// chat routes
app.get('/chat', (request, response) => {
    let pageTitle = "Chat page"
    response.render('chat', {pageTitle});
})

create a view file called chat.handlebars and add a form like below:

<div class="container">
    <div class="row">
        <div class="col-sm-8">
            <h3>Chat me Here!!!</h3>
            <ul id="messages"></ul>
            <form>
                <div class="form-group">
                    <label for="inputName">Your Name</label>
                    <input type="text" class="form-control" id="name" placeholder="Give your name...">
                </div>
                <div class="form-group">
                    <label for="inputMessage">Your messages</label>
                    <input type="text" class="form-control" id="message" placeholder="type here...">
                </div>
                <button type="submit" class="btn btn-primary">Send Message</button>
            </form>
        </div>
        <div class="col-sm-4"><h3>Users</h3></div>
    </div>
</div>

Here:

    • will show all messages from the chats with messages id from using jquery.
  • container has two div column one is for showing messages for chat app and second one is to show users list and their status like online or offline etc.

Now add the Jquery from cdn to the index file because we need jquery for client-side.

<script src="https://code.jquery.com/jquery-1.11.1.js"></script> //in index.handlebars

Add below codes in your index file:

    $(function () {
        const socket = io();
        // form from chat.handlebars when submit anything
        $('form').submit(function () {
            // name class will get data value from input and save to name variable
            const name = $('#name').val();
            // message class will get data value from input and save to message variable
            const message = $('#message').val();
            // emit a string or data using name and message from input variable and send to chatMsg event
            socket.emit('chatMsg', `${name} said : ${message}`);
            $('#message').val('');
            // do not return anything so we can see msgs and stay on the same page without reloading
            return false;
        });

        socket.on('chatMsg', function (message) {
            // adding all messages sending and receiving using list and append()
            $('#messages').append($('<li style="background-color: #e5ecef; color: black;">').text(message));
        });
        // socket.emit('chatMsg', 'Hi from client');
    });

Now in app.js file add below code for server side:

// include socket io for ther server
const io = require('socket.io').listen(server)

io.on('connection', function (socket) {
    console.log('a user is connected...');
    // receive messages from chatMSg event of client
    socket.on('chatMsg', function(message) {
        console.log('Received Message is : ' + message);
        // broadcasting the message to all connected users of chatMsg event
        io.emit('chatMsg', message);
    });
});

Check the app now by opening two tabs: localhost:5000/chat and see what happens in console also.

Check my next tute for more updates and functionality on this chat app.

;)

⚠️ **GitHub.com Fallback** ⚠️