Building a Real-Time Chat Application with Node.js and Pusher

Real-time chat applications have become an essential part of our daily lives. Whether it is communicating with our loved ones, colleagues or clients, the ability to instantly connect with someone can make a huge difference in our personal and professional lives. In this article, we will explore how to build a real-time chat application with Node.js and Pusher, a platform that provides easy-to-use APIs and services for building real-time features.

Node.js is a popular runtime environment that allows developers to build fast and scalable applications with JavaScript. It provides a non-blocking, event-driven I/O model that makes it ideal for building real-time applications. Pusher, on the other hand, is a real-time communication platform that provides APIs and services for building real-time features such as chat, notifications, and data synchronization.

Getting Started

To get started, we need to create a new Node.js project and install the required dependencies. We will be using Express.js as our web framework and Socket.io for real-time communication.

lua
npm init
npm install express socket.io pusher --save

Next, let’s create a new file named index.js and add the following code:

javascript
const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');
  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});

This code creates a new Express.js app and a new Socket.io server that listens for incoming connections on port 3000. We also define a simple route that serves an HTML file and a connection event handler that logs when a new user connects and disconnects from the server.

Let’s create the index.html file and add some basic HTML code:

php
<!DOCTYPE html>
<html>
  <head>
    <title>Real-Time Chat Application</title>
  </head>
  <body>
    <h1>Real-Time Chat Application</h1>
    <div id="messages"></div>
    <form action="">
      <input id="message" autocomplete="off" /><button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      var socket = io();
      $('form').submit(function(){
        socket.emit('chat message', $('#message').val());
        $('#message').val('');
        return false;
      });
      socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
      });
    </script>
  </body>
</html>

This code creates a simple HTML form that allows users to send messages to the server. When a user submits the form, a new chat message event is emitted to the server with the message text. The server then broadcasts this message to all connected clients, which updates the messages list.

Now that we have a basic chat application running, let’s integrate Pusher to add real-time functionality.

Integrating Pusher

To integrate Pusher, we first need to create a new account and a new app on the Pusher website. Once we have created a new app, we can get our APP_ID, APP_KEY and APP_SECRET credentials, which we will use to authenticate and communicate with Pusher.

Let’s update our index.js file to include Pusher:

javascript
const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const Pusher = require('pusher');

const pusher = new Pusher({
  appId: 'APP_ID',
  key: 'APP_KEY',
  secret: 'APP_SECRET',
  cluster: 'APP_CLUSTER',
  useTLS: true
});

app.use(express.static('public'));

app.post('/pusher/auth', (req, res) => {
  const socketId = req.body.socket_id;
  const channel = req.body.channel_name;
  const auth = pusher.authenticate(socketId, channel);
  res.send(auth);
});

io.on('connection', (socket) => {
  console.log('a user connected');
  socket.on('chat message', (msg) => {
    pusher.trigger('chat', 'message', { message: msg });
  });
  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
});

http.listen(3000, () => {
  console.log('listening on *:3000');
});

In this code, we first import the Pusher module and create a new instance of the Pusher class with our app credentials. We then define a new route that handles Pusher authentication, which is required to subscribe to private and presence channels.

Next, we update our connection event handler to trigger a new chat message event on Pusher whenever a new message is received from a client. This event includes the message text and is broadcasted to all subscribed clients.

Finally, we update our HTML file to use the Pusher client library instead of Socket.io:

php

<!DOCTYPE html>
<html>
  <head>
    <title>Real-Time Chat Application</title>
  </head>
  <body>
    <h1>Real-Time Chat Application</h1>
    <div id="messages"></div>
    <form action="">
      <input id="message" autocomplete="off" /><button>Send</button>
    </form>
    <script src="https://js.pusher.com/7.0/pusher.min.js"></script>
    <script>
      var pusher = new Pusher('APP_KEY', {
        cluster: 'APP_CLUSTER',
        encrypted: true,
        authEndpoint: '/pusher/auth'
      });
      var channel = pusher.subscribe('private-chat');
      channel.bind('message', function(data) {
        $('#messages').append($('<li>').text(data.message));
      });
      $('form').submit(function(){
        var message = $('#message').val();
        $.ajax({
          method: 'POST',
          url: '/pusher/auth',
          data: {
            socket_id: pusher.connection.socket_id,
            channel_name: 'private-chat'
          }
        }).done(function(data) {
          channel.trigger('client-message', { message: message });
          $('#message').val('');
        });
        return false;
      });
    </script>
  </body>
</html>

This code creates a new Pusher client instance and subscribes to a new private channel named private-chat. When a new message is received from the server, it updates the messages list. When a user submits the form, a new client-message event is triggered on the private channel, which sends the message text to the server for broadcasting to all subscribed clients.

Conclusion

In this article, we have explored how to build a real-time chat application with Node.js and Pusher. We started by creating a basic chat application using Socket.io and Express.js, and then integrated Pusher to add real-time functionality. Pusher makes it easy to build real-time features like chat applications by handling the complexity of WebSockets and scaling infrastructure for you. With Pusher, you can easily build real-time applications without worrying about infrastructure or complex code. I hope this tutorial has been helpful in getting you started with building real-time chat applications using Node.js and Pusher. 

0368826868