Real-Time Messaging: Ably's Approach and Seamless Integration with React Apps

Introduction to real-time messaging

Real-time messaging, abbreviated as RTM, is a communication technology that enables the near-instantaneous exchange of information between users regardless of their locations. This exchange of information, encompassing both synchronous and asynchronous modes, leverages specific protocols and standards including WebSocket, XMPP (Extensible Messaging and Presence Protocol), and MQTT (Message Queuing Telemetry Transport).
Common use cases of RTM include chat applications, management tools, Internet of Things, and online gaming.

Existing solutions out there

Existing solutions shaping the landscape of RTM can be broadly categorized into two: client-server architecture and peer-to-peer architecture.

  1. Client-Server Architecture:

    Client-server architecture gives centralized control and allows for scalability and a wide range of feature inclusion. RTM solutions utilizing client-server architecture include WebSocket, Extensible Messaging and Presence Protocol (XMPP), Pusher, and Firebase Cloud Messaging.

  2. Peer-to-Peer Architecture:
    In peer-to-peer (P2P) architecture, clients communicate directly with each other without a central server. This enhances data privacy and removes the delay associated with passing data via servers. While most popular RTM solutions employ client-server architecture, there are a few P2P-based solutions available. Examples of P2P-based RTM solutions include Oppo's MeshTalk, Tox and WhisperText.

Problems with existing solutions

Real-time messaging (RTM) has revolutionized communication, however, selecting the right RTM solution requires meticulous consideration of the potential downsides.

WebSocket: Balancing Security and Complexity

WebSocket - which seems to be the most common solution - is typically unencrypted and thus, susceptible to Man-in-the-Middle (MITM) attacks. Server-side implementation can also be complex, especially when handling large numbers of concurrent connections. Furthermore, WebSocket's focus on synchronous communication makes it less suitable for use cases that require asynchronous message delivery.

XMPP: Balancing Complexity and Adoption

XMPP's XML-based protocol and numerous extensions present a steep learning curve, posing a challenge to implementation and maintenance. Additionally, its adoption in consumer applications is relatively limited compared to other RTM protocols. Improper XMPP server configuration can also lead to resource exhaustion, particularly in high-traffic environments.

MQTT: Striking a Balance Between Features and Latency

MQTT's lightweight messaging approach results in a more limited feature set compared to other RTM protocols. Its publish-subscribe model, while efficient for resource utilization, is not ideal for real-time chat applications due to its relatively high latency. Moreover, MQTT's lack of default encryption necessitates careful implementation of security measures to protect against unauthorized access.

Pusher: Navigating Vendor Lock-in and Data Privacy

While Pusher's cloud-based service simplifies RTM implementation, it can lead to vendor lock-in, making it difficult to switch to other solutions. Pusher's reliance on external services may also raise concerns about data privacy and control.

Firebase Cloud Messaging (FCM): Balancing Google Dependency

FCM's dependence on Google's infrastructure raises concerns about data privacy and potential vendor lock.

How Ably solves for RTM

Ably reliably distributes real-time data to clients using the publish-subscribe messaging pattern over WebSocket connections, while also managing your integrations and connectors. It has extensive language/library support including Vanilla Javascript, Java, Python, Golang, Ruby, .Net, React, PHP, Swift, and NodeJS.

Ably is engineered around the pillars of dependability - Performance, Integrity, Reliability and Reliability - aimed at providing seamless developer and user experiences. Its modern system architecture allows for:

  • minimized latency and high throughput

  • guaranteed data ordering and delivery

  • high scalability

  • regional and global fault tolerance

Aside from being SOC 2 Type 2 certified and HIPAA compliant, Ably's publish-subscribe channels provide robust security mechanisms including:

  • DoS protection and rate limiting.

  • Message-level encryption.

  • Flexible authentication (API keys and tokens), with highly specific access control.

With companies including Hubspot, Split and Experity building on Ably, it is safe to conclude Ably works well for large-scale companies.

How to build a basic chat app with React using the Ably API

With Ably's robust real-time messaging platform, developing a chat app using React has become remarkably straightforward. This guide will walk you through the process of creating a basic chat app with React and Ably.

Prerequisites:

  • Node.js installed

  • Basic understanding of React and JavaScript

Step 1 – Create your Ably app

Step 2 - Create a React App

Initialize a new React project using Create React App:

npx create-react-app basic-chat-app

Step 3 - Install Ably React

Change the directory into basic-chat-app and install the Ably react package using npm or yarn.

cd basic-chat-app
npm install --save ably

Step 4 - Configure Ably

  • Copy the API key on your dashboard

  • Create a .env file in the root directory of your React project and add your Ably API key

      ABLY_API_KEY=<your-ably-api-key>
    
  • Create an endpoint to handle token requests:

      import Ably from "ably/promises";
      const rest = new Ably.Rest(process.env.ABLY_API_KEY);
    
      app.get("/ably/auth", (req, res) => {
        const tokenParams = {
          clientId: "my-client-id",
        };
        rest.auth.createTokenRequest(tokenParams, (err, tokenRequest) => {
          if (err) {
            res.status(500).send("Error requesting token: " + JSON.stringify(err));
          } else {
            res.setHeader("Content-Type", "application/json");
            res.send(JSON.stringify(tokenRequest));
          }
        });
      })
    

In your React App component, create a new instance of an Ably client and provide that to the AblyProvider

//App.js
import * as Ably from 'ably'
import { AblyProvider } from 'ably/react';
import Chat from "../Chat";

const App = ()=> {
const client = Ably.Realtime.Promise({ authUrl: '[YOUR_ABLY_TOKEN_API_URL_PATH]'});
return (
  <AblyProvider client={ client }>
  //  <Chat />
  </AblyProvider>
);
}

Step 5 - Create a Chat Component

  • use the useChannel hook within a child component of AblyProvider to connect and subscribe to a channel
//Chat.jsx
import { useChannel } from "ably/react";

export default const Chat = () => {
    const [messages, setMessages] = useState([]);
    const [inputMessage, setInputMessage] = useState('');
    // Subscribe to the channel
    const { channel }  = useChannel("channel-name", (message) => {
      setMessages((prev) => [...prev, message]);
      });       
     const sendMessage = () => {
       channel.publish("message", { text: inputMessage });
        setInputMessage('');
      };

    return (
        <>
          <div>
            {messages.map((msg, index) => (
              <div key={index}>{msg}</div>
            ))}
           </div>    
          <div>
            <input
              type="text"
              value={inputMessage}
              onChange={(e) => setInputMessage(e.target.value)}
            />
            <button onClick={sendMessage}>Send</button>
          </div>
        </>
            )

Step 6 - Run the App

npm start

Your chat app should now be running. Open your browser and navigate to http://localhost:3000 to see the app in action.

Happy Hacking!