Note worthy📝
- This article assumes that you already have node.js installed on your computer. If you haven't, kindly do so here
Lets begin!
This write up hopes to walk you through the process of building a very simple 2 layer chat application.
Lets start by building the backend
- Create a folder and name it whatever you want, I'll be naming mine SOCKET-APPLICATION-SERVER.
- Now you can use any IDE of your choice to open the folder. I prefer to use VScode.
- Open the terminal in this folder and initiate your node project with npm init. This command compiles all the main details of the your application such as name, version, description etc into apackage.jsonfile.  
- Now create your entry point file and give it a name of your choice. I'll name mine app.js.
- Download the socket.iopackage by by runningnpm install socket.ioin the terminal.
- set up your server in the the app.jsfile with the code below.
const httpServer = require('http').createServer((req, res) => {
    res.setHeader('Access-Control-Allow-Origin', `${front end server link}`);
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    res.setHeader('Access-Control-Allow-Credentials', true);
  });
- Now require the socket.iopackage and create an object from it.
 const io = require('socket.io')(httpServer, {
    cors: {
      origin: `${front end server link}`,
      methods: ["GET", "POST"],
      credentials: true
    }
  });
- Use the socket object created earlier (io) to initiate the connection.
io.on('connection', socket => {
  });
- Now we are going receive the user's name entry from the frontend (this will make a lot more sense when we start building the frontend).
io.on('connection', socket => {
//new code added
   socket.on('username', username => {
      users[socket.id] = username
      socket.broadcast.emit('user-in', username)
    })
//new code added
  });
- Since we now how the user's name after they connect, we can now worry about the user's (sender) message. We going to broadcast the user's (sender) message with to anyone one else online. We will do this by first receiving the message that tagged with send-chat-messagethen emit it with achat-messagetag. The tages help to distinguish between the messages coming in and those going out.
io.on('connection', socket => {
   socket.on('username', username => {
      users[socket.id] = username
      socket.broadcast.emit('user-in', username)
    })
//new code added
  socket.on('send-chat-message', msg => {
        socket.broadcast.emit('chat-message', {message: msg, 
  name: users[socket.id]})
    })
//new code added
  });
- We would like to notify the receiver once the sender disconnects or vice-versa.
  const users = {}
io.on('connection', socket => {
   socket.on('username', username => {
      users[socket.id] = username
      socket.broadcast.emit('user-in', username)
    })
 socket.on('send-chat-message', msg => {
        socket.broadcast.emit('chat-message', {message: msg, 
  name: users[socket.id]})
    })
//new code added
 socket.on('disconnect', () => {
      socket.broadcast.emit('user-disconnected', users[socket.id])
      delete users[socket.id]
    })
//new code added
  });
- Finally set the port for the server and listen for requests
  const PORT = process.env.PORT || 3000;
  httpServer.listen(PORT, () => console.log(`Running server on 🚀. \nListening on ${ PORT } 👂`));
- Start the server by running node app.jsin the terminal. You can consider using nodemon which automatically refreshes your server anytime you make a change.
Lets start building the frontend
To aid with proper understanding the front end will run on a separate server.
- Create a folder and name it whatever you want, I'll be naming mine SOCKET-APPLICATION-CLIENT.
- Open the folder in your IDE.
- Run npm initin the terminal for this folder
- Download the socket.iopackage by by runningnpm install socket.ioin the terminal.
- create a simple index.htmlfile with the following body.
<body>
        <div id="message-container">
        </div>
            <div  id="send-container">
                <input name=""  placeholder="Type your message..." type="text" id="message-input"> 
                <button id="end-button"  type="submit">
                    <span  id="submits">
                        <i class="fas fa-location-arrow"></i>
                    </span>
                </button> 
            </div>
    </body>
- Add the following script links inside your index.html <head>tag. Thesocket.ioinstance will be created and sent from the backend. Thescript.jsfile will use the instance to send and receive messages.
<script defer src="http://localhost:3000/socket.io/socket.io.js"></script>
<script defer src="./script.js"></script>
- Also download the nodemonpackage by by runningnpm install nodemonin the terminal. This will restart your frontend server anytime you make a changes.
- Now create your entry point file: app.js.
- Set up your server in the the app.jsby first runningnpm install express. We'll need express to server static files like ourindex.htmlpage.
- Now fill the app.jspage with the code below.
var express = require('express'), app = express() 
app.use('/', express.static('public'));
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => console.log(`Running server on 🚀. \nListening on ${ PORT } 👂`));
- Create the scripts.js file we linked to the index.htmlearlier. In the file, start by getting all the need DOM elements.
const mesaageForm = document.getElementById("submits")
const messageInput = document.getElementById('message-input')
const messageContainer = document.getElementById('message-container')
const userInfo = document.getElementById('user-info')
- Connect to the front end to backend socket
// connect to the server socket
const socket = io('http://localhost:3000', {
  withCredentials: true
});
- Allow the socket to listen for messages. Only append the message to the receiver's view if it is not empty
//listen to the socket for content with the tag 'chat-message'
socket.on('chat-message', data => {
    if (data.message != "") {
      appendMessage(`${data.name}: ${data.message}`)
    }
})
- Since we want to notify the receiver if sender disconnects or vice versa, we will use the socket to listen for disconnections.
//listen to the socket for user disconnection
socket.on('user-disconnected', name => {
  appendMessage(`${name}: disconnected`)
})
- Now that our application is listening for all the necessary changes and messages, we can move on to obtaining the user's name
//ask the user for their name
const username = prompt('What is your name ?😃')
socket.emit('username', username)
- Now we need to write functions that will append new messages to the screen for both the sender and receiver.
// send message to reciever
function appendMessage(message){
  let man = messageContainer.scrollHeight + 500;
  messageContainer.scroll = man
  var wrapper= document.createElement('div');
wrapper.innerHTML = `
    <div>
      <p>${message}</p>
    </div>
              `
      messageContainer.append(wrapper)
}
//show message on sender's screen
function appendMessageForMe(message){
  messageContainer.scrollTop = messageContainer.scrollHeight;
  var wrapper= document.createElement('div');
wrapper.innerHTML = `
  <div>
      <p>${message}</p>
    </div>
              `
      messageContainer.append(wrapper)
}
- Finally we are going to use the event listener to activate the functions we just created whenever the user wants to send a message. To make things easier, we will activate the function when the user taps/clicks the send button, or presses the enter button after they have typed a message.
// if the user taps the send button or presses enter key, the message should be sent.
mesaageForm.addEventListener('click', e =>{
    e.preventDefault()
    const message  = `${messageInput.value}`
    if (message != "") {
      // the emit method sends the message out with the tag: 'send-chat-message' 
      socket.emit('send-chat-message', message)
      appendMessageForMe(message)
      messageInput.value = ''
    }
})
messageInput.addEventListener('keydown', e =>{
  if (e.key === "Enter") {
    e.preventDefault()
    const message  = `${messageInput.value}`
    if (message != "") {
      socket.emit('send-chat-message', message)
      appendMessageForMe(message)
      messageInput.value = ''
    }
  }
})
- Run nodemonin the terminal and go tohttp://localhost:8000/
- Don't forget to also run the backend server.
Conclusion
- we built a backend server that uses socket.io to recieve and reroute our messages to available users
- we also built a very simple 😅 frontend to demonstrate the exchange of messages
- Don't forget to add your enhancements after you try this. I have an advanced version of this application on my repository. Check the backend out here here and the front end out here
    
 
 
              
 
    
Top comments (0)