Popular Searches
Popular Course Categories
Popular Courses

Working with WebSockets and Real-Time Communication

Working with WebSockets and Real-Time Communication

Third-Party Integrations and Application Architecture

Working with WebSockets and Real-Time Communication in React Native

Course: React Native Training

Topic: Working with WebSockets and Real-Time Communication

Course Link: React Native Training at JustAcademy

Demo Link: Register for a Course Demo

JustAcademy Website: Visit JustAcademy


1. Introduction to Real-Time Communication

Real-time communication allows an application to exchange information between a client and a server with minimal delay. In React Native, this capability is useful when users need immediate updates without manually refreshing the screen.

Examples include chat applications, live delivery tracking, multiplayer games, collaborative editing, stock dashboards, notifications, and customer support systems.

Traditional applications often retrieve information by making HTTP requests whenever a user opens a screen or presses a button. Real-time applications can maintain a communication channel and receive updates when the server has new information.

1.1 What Is Real-Time Communication?

Real-time communication is the exchange of information between connected systems as events occur. It does not necessarily guarantee zero delay; actual performance depends on network quality, server processing, device conditions, and application design.

1.2 Why Is Real-Time Communication Important?

  • Provides immediate updates without requiring manual refresh.
  • Improves the responsiveness of interactive applications.
  • Enables live messaging and presence indicators.
  • Supports live location and delivery status updates.
  • Allows multiple users to receive shared information.
  • Reduces repeated requests when a persistent communication channel is appropriate.
  • Helps applications deliver time-sensitive information.

1.3 Common Real-Time Application Examples

Application Real-Time Feature
Messaging application Instant messages and typing indicators.
Food delivery application Live order and delivery status updates.
Ride-booking application Driver location and trip status updates.
Collaborative application Shared changes across multiple users.
Customer support application Live conversations between customers and agents.
Gaming application Player actions and game-state updates.
Financial dashboard Streaming market or account information where supported.

2. Understanding WebSockets

WebSocket is a communication protocol that establishes a persistent, two-way communication channel between a client and a server. Once the connection is established, both sides can send messages independently without creating a new HTTP request for every message.

React Native provides a global WebSocket interface that can be used to connect to a compatible WebSocket server. The connection and event-handling model is similar to the standard WebSocket API used in web development. React Native WebSocket documentation.

2.1 How WebSockets Work

  1. The React Native application creates a WebSocket connection to a server.
  2. The client and server establish the connection through a handshake.
  3. The connection remains open while both sides keep it active.
  4. The client can send messages to the server.
  5. The server can send messages to the client at any time.
  6. The connection closes when either side closes it or a network or server failure interrupts it.

2.2 WebSocket Communication Diagram

React Native Application
          |
          | Establish connection
          v
     WebSocket Server
          |
          | Connection established
          v
     Persistent Channel
          |
          +----------------------+
          |                      |
          v                      v
Client sends message     Server sends update
          |                      |
          v                      v
Server processes it      App receives message
          |                      |
          +----------+-----------+
                     |
                     v
             UI updates in real time

2.3 WebSocket URL Schemes

  • ws:// – WebSocket communication without transport-layer encryption.
  • wss:// – WebSocket communication protected by TLS encryption.

Production applications should normally use wss://. Plain ws:// may expose communication to interception and can be blocked by security restrictions in some environments.

3. WebSockets vs. HTTP Requests

HTTP and WebSockets serve different communication needs. HTTP is commonly used for ordinary request-response operations, while WebSockets are useful when a long-lived, bidirectional connection is required.

Feature HTTP WebSocket
Communication model Typically request-response. Two-way communication over a persistent connection.
Connection usage Requests are made as needed; transport connections may be reused. A connection is maintained while active.
Server-initiated updates Usually require polling, streaming, or another mechanism. Server can send messages at any time after connection establishment.
Typical use cases Login, product lists, profile data, and form submission. Chat, live dashboards, presence, and interactive collaboration.
Infrastructure Commonly supported by standard HTTP infrastructure. Requires compatible WebSocket support across server and infrastructure.
Connection management Generally managed per request and transport behavior. Requires lifecycle, reconnection, and heartbeat planning.

3.1 When Should You Use WebSockets?

Use WebSockets when the application benefits from continuous two-way communication and frequent event updates.

  • Real-time chat and messaging.
  • Live notifications that need immediate delivery while connected.
  • Shared collaborative editing.
  • Interactive dashboards with frequent updates.
  • Multiplayer games that require rapid exchange of state.

3.2 When Is HTTP Enough?

HTTP is usually sufficient when information is retrieved occasionally or when the client only needs to submit a request and receive a response.

  • Loading a product catalogue.
  • Submitting a registration form.
  • Retrieving a user profile.
  • Uploading a document.
  • Creating an order.

Many applications combine both approaches: HTTP for initial data retrieval and ordinary operations, and WebSockets for live updates.

4. Other Real-Time Communication Technologies

WebSockets are not the only option for real-time functionality. The best technology depends on the communication pattern, infrastructure, and application requirements.

Technology Communication Pattern Common Use
WebSockets Bidirectional, persistent communication. Chat and collaborative features.
HTTP polling Client repeatedly requests updates. Simple applications with infrequent updates.
Long polling Server holds an HTTP request until data is available or a timeout occurs. Real-time-like updates where WebSockets are unavailable.
Server-Sent Events (SSE) Server-to-client event stream over HTTP. Live feeds and one-way status updates, where supported.
WebRTC Peer-to-peer media or data communication, usually with signaling infrastructure. Audio calls, video calls, and peer data transfer.
Managed real-time services Provider-managed event delivery and connection infrastructure. Chat, presence, notifications, and synchronized data.

5. Creating a Basic WebSocket Connection in React Native

The global WebSocket object allows an application to create a connection, listen for events, send messages, and close the connection. A connection is established asynchronously, so messages should only be sent when the socket is open. MDN WebSocket API reference.

5.1 Basic Connection Example

const socket = new WebSocket(
  'wss://your-websocket-server.example.com'
);

socket.onopen = () => {
  console.log('WebSocket connected');
};

socket.onmessage = event => {
  console.log('Message received:', event.data);
};

socket.onerror = error => {
  console.log('WebSocket error:', error);
};

socket.onclose = event => {
  console.log(
    'WebSocket closed:',
    event.code,
    event.reason
  );
};

This example demonstrates the main WebSocket events. The URL is illustrative and must be replaced with an actual WebSocket endpoint. The server must implement a compatible WebSocket protocol and message format.

5.2 Main WebSocket Events

Event Purpose
open Indicates that the connection has been established.
message Indicates that the server has delivered a message.
error Indicates that a connection or communication error occurred.
close Indicates that the connection has closed.

5.3 WebSocket Ready States

The readyState property indicates the current connection state.

Constant Value Meaning
CONNECTING 0 The connection is being established.
OPEN 1 The connection is open and can exchange data.
CLOSING 2 The connection is in the process of closing.
CLOSED 3 The connection is closed or could not be established.

6. Sending and Receiving Messages

After the connection opens, the client can send data using send(). The server can return a response or send a new event independently of a client request.

6.1 Sending a Text Message

const socket = new WebSocket(
  'wss://your-websocket-server.example.com'
);

socket.onopen = () => {
  socket.send('Hello from React Native');
};

Calling send() while the connection is still connecting can throw an error. Check that the connection is open before sending.

6.2 Receiving a Message

socket.onmessage = event => {
  const message = event.data;

  console.log('Server message:', message);
};

The received data may be text or binary data, depending on the protocol and server implementation. Your application should understand the format agreed upon with the server.

6.3 Sending JSON Messages

Many real-time applications use JSON to represent structured events.

const message = {
  type: 'chat_message',
  conversationId: 'conversation_101',
  text: 'Hello everyone',
  sentAt: new Date().toISOString(),
};

if (socket.readyState === WebSocket.OPEN) {
  socket.send(JSON.stringify(message));
}

6.4 Parsing Incoming JSON

socket.onmessage = event => {
  try {
    const message = JSON.parse(event.data);

    switch (message.type) {
      case 'chat_message':
        console.log('Chat message:', message.text);
        break;

      case 'notification':
        console.log('Notification:', message.title);
        break;

      default:
        console.log('Unknown message type');
    }
  } catch (error) {
    console.log('Received an invalid message format');
  }
};

Always validate message structure before using it. Data received over a socket should be treated as untrusted input, even when the connection uses encryption.

7. Building a Reusable WebSocket Service

For a larger application, placing connection setup in every screen can cause duplicated logic and multiple unwanted connections. A dedicated service can centralize connection creation, event listeners, and cleanup.

7.1 Why Use a WebSocket Service?

  • Centralizes connection management.
  • Separates network communication from UI code.
  • Provides a consistent interface for sending and receiving messages.
  • Makes connection logic easier to test.
  • Reduces duplicated code across screens.
  • Allows authentication and reconnection policies to be managed centrally.

7.2 Creating a WebSocket Service

Create a file named webSocketService.js inside the services folder.

class WebSocketService {
  socket = null;
  listeners = new Map();

  connect(url) {
    if (
      this.socket &&
      (
        this.socket.readyState === WebSocket.OPEN ||
        this.socket.readyState === WebSocket.CONNECTING
      )
    ) {
      return;
    }

    const socket = new WebSocket(url);
    this.socket = socket;

    socket.onopen = event => {
      this.emit('open', event);
    };

    socket.onmessage = event => {
      this.emit('message', event.data);
    };

    socket.onerror = event => {
      this.emit('error', event);
    };

    socket.onclose = event => {
      this.emit('close', event);

      if (this.socket === socket) {
        this.socket = null;
      }
    };
  }

  send(data) {
    if (
      !this.socket ||
      this.socket.readyState !== WebSocket.OPEN
    ) {
      return false;
    }

    this.socket.send(
      typeof data === 'string'
        ? data
        : JSON.stringify(data)
    );

    return true;
  }

  subscribe(eventName, callback) {
    if (!this.listeners.has(eventName)) {
      this.listeners.set(eventName, new Set());
    }

    const callbacks = this.listeners.get(eventName);
    callbacks.add(callback);

    return () => {
      callbacks.delete(callback);

      if (callbacks.size === 0) {
        this.listeners.delete(eventName);
      }
    };
  }

  emit(eventName, payload) {
    const callbacks = this.listeners.get(eventName);

    if (!callbacks) return;

    callbacks.forEach(callback => {
      callback(payload);
    });
  }

  disconnect() {
    if (this.socket) {
      const socket = this.socket;
      this.socket = null;
      socket.close(1000, 'Client disconnected');
    }
  }
}

const webSocketService = new WebSocketService();

export default webSocketService;

This service is a starting point for a single active connection. A production implementation should also account for reconnection, authentication, heartbeat checks, app lifecycle transitions, message validation, and connection ownership. Avoid sharing one connection across unrelated user sessions without proper cleanup.

7.3 Using the Service

import webSocketService from '../services/webSocketService';

webSocketService.connect(
  'wss://your-websocket-server.example.com'
);

const unsubscribe = webSocketService.subscribe(
  'message',
  message => {
    console.log('Received:', message);
  }
);

webSocketService.send({
  type: 'subscribe',
  channel: 'general',
});

// When this consumer no longer needs the events:
unsubscribe();

In a real application, connection initialization should be owned by an appropriate application-level provider or lifecycle manager. A screen should generally unsubscribe from its listeners when it unmounts, rather than closing a shared connection that other screens still need.

8. Using WebSockets with React Hooks

Custom hooks can connect React state to WebSocket events. They allow components to receive connection status and messages without duplicating low-level event-handling logic.

8.1 Creating a Custom WebSocket Hook

Create a file named useWebSocket.js inside the hooks folder.

import { useEffect, useRef, useState } from 'react';

export default function useWebSocket(url) {
  const socketRef = useRef(null);
  const [status, setStatus] = useState('connecting');
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    if (!url) return;

    let active = true;
    const socket = new WebSocket(url);

    socketRef.current = socket;

    socket.onopen = () => {
      if (active) {
        setStatus('connected');
      }
    };

    socket.onmessage = event => {
      if (!active) return;

      setMessages(previous => [
        ...previous,
        event.data,
      ]);
    };

    socket.onerror = () => {
      if (active) {
        setStatus('error');
      }
    };

    socket.onclose = () => {
      if (active) {
        setStatus('disconnected');
      }
    };

    return () => {
      active = false;

      socket.onopen = null;
      socket.onmessage = null;
      socket.onerror = null;
      socket.onclose = null;

      if (
        socket.readyState === WebSocket.OPEN ||
        socket.readyState === WebSocket.CONNECTING
      ) {
        socket.close();
      }

      if (socketRef.current === socket) {
        socketRef.current = null;
      }
    };
  }, [url]);

  const sendMessage = message => {
    const socket = socketRef.current;

    if (
      socket &&
      socket.readyState === WebSocket.OPEN
    ) {
      socket.send(
        typeof message === 'string'
          ? message
          : JSON.stringify(message)
      );

      return true;
    }

    return false;
  };

  return {
    status,
    messages,
    sendMessage,
  };
}

This hook opens a connection when the URL changes and closes it during cleanup. It is suitable as a basic learning example, but it does not implement automatic reconnection, authentication, bounded message history, or application-wide connection sharing.

8.2 Using the Hook in a Screen

import React, { useState } from 'react';
import {
  View,
  Text,
  TextInput,
  Pressable,
  FlatList,
} from 'react-native';

import useWebSocket from '../hooks/useWebSocket';

export default function LiveMessagesScreen() {
  const [input, setInput] = useState('');

  const {
    status,
    messages,
    sendMessage,
  } = useWebSocket(
    'wss://your-websocket-server.example.com'
  );

  const handleSend = () => {
    const text = input.trim();

    if (!text) return;

    const sent = sendMessage({
      type: 'chat_message',
      text,
    });

    if (sent) {
      setInput('');
    }
  };

  return (
    <View style={{ flex: 1, padding: 16 }}>
      <Text>Connection: {status}</Text>

      <FlatList
        data={messages}
        keyExtractor={(_, index) => String(index)}
        renderItem={({ item }) => (
          <Text>{String(item)}</Text>
        )}
      />

      <TextInput
        value={input}
        onChangeText={setInput}
        placeholder="Enter a message"
      />

      <Pressable onPress={handleSend}>
        <Text>Send Message</Text>
      </Pressable>
    </View>
  );
}

This example displays raw incoming messages. A real chat application should parse and validate the message format, display structured message objects, manage stable message IDs, and handle acknowledgements and delivery status.

9. Creating a Real-Time Chat Application

Chat is one of the most common applications of WebSockets. It requires communication between users, message delivery, conversation management, and often additional features such as read receipts, typing indicators, and online presence.

9.1 Main Chat Features

  • Send and receive messages.
  • Display messages in chronological order.
  • Show connection and delivery status.
  • Receive messages while the conversation is open.
  • Support conversation rooms or channels.
  • Handle duplicate messages and reconnection.
  • Load earlier messages through an HTTP API when appropriate.
  • Authenticate users and authorize access to conversations.

9.2 Suggested Chat Message Structure

{
  "type": "chat_message",
  "messageId": "msg_1001",
  "conversationId": "conv_2001",
  "senderId": "user_101",
  "text": "Hello!",
  "sentAt": "2026-10-21T10:00:00.000Z"
}

This JSON illustrates a possible message format. The actual protocol must be agreed upon between the client and server. The backend should assign or validate message identifiers and timestamps rather than trusting the client blindly.

9.3 Typical Chat Message Flow

  1. The user types a message and presses Send.
  2. The application validates the input.
  3. The client sends the message through the active WebSocket.
  4. The server authenticates the sender and checks conversation permissions.
  5. The server stores the message if persistent history is required.
  6. The server sends the accepted message to authorized recipients.
  7. The clients update their message lists.
  8. Delivery and read receipts are handled as separate events when supported.

9.4 Important Chat Considerations

  • Use stable message IDs instead of array indexes for React list keys.
  • Prevent duplicate display when the server echoes a message already shown optimistically.
  • Distinguish sending, sent, delivered, and read states.
  • Use pagination or history APIs for older messages.
  • Handle message ordering and delayed events.
  • Validate message length and content on both client and server.
  • Implement authorization so users can only access permitted conversations.

10. Real-Time Notifications

WebSockets can deliver in-app notifications while the application maintains an active connection. For example, a shopping application may receive an order-status update or a customer-support application may receive a new reply.

10.1 Notification Event Example

{
  "type": "notification",
  "notificationId": "notif_501",
  "title": "Order Update",
  "body": "Your order has been dispatched.",
  "createdAt": "2026-10-21T10:15:00.000Z"
}

10.2 Handling Notification Events

function handleSocketMessage(rawData) {
  try {
    const event = JSON.parse(rawData);

    if (event.type === 'notification') {
      // Validate required fields before displaying.
      if (
        typeof event.title === 'string' &&
        typeof event.body === 'string'
      ) {
        console.log(
          'Notification:',
          event.title,
          event.body
        );
      }
    }
  } catch {
    console.log('Invalid notification payload');
  }
}

WebSockets are not a complete replacement for mobile push notifications. If a user closes the application or the operating system suspends it, an active socket may no longer be available. Background and terminated-app notifications usually require a suitable push notification service and platform-specific configuration.

11. Real-Time Location and Tracking

Delivery, transport, and field-service applications can use WebSockets to exchange location updates between authorized devices and a backend.

11.1 Example Location Event

{
  "type": "location_update",
  "tripId": "trip_501",
  "latitude": 19.0760,
  "longitude": 72.8777,
  "recordedAt": "2026-10-21T10:20:00.000Z"
}

11.2 Implementation Considerations

  • Request location permissions according to platform requirements.
  • Transmit only the location information necessary for the feature.
  • Validate coordinates and timestamps on the backend.
  • Control update frequency to reduce battery and network usage.
  • Authenticate connections and authorize access to each trip or delivery.
  • Stop location collection when it is no longer needed.
  • Explain location use clearly and follow applicable privacy requirements.

12. Reconnection and Network Failure Handling

Mobile networks are not always reliable. A device may lose connectivity in an elevator, switch from Wi-Fi to mobile data, enter a tunnel, or temporarily suspend application activity. A robust real-time feature should recover gracefully when the connection is lost.

12.1 Why Reconnection Is Necessary

  • Wi-Fi or mobile data may become unavailable.
  • The server may restart or become temporarily unreachable.
  • The application may return from the background.
  • A proxy or load balancer may close an idle connection.
  • The user's authentication session may expire.

12.2 Exponential Backoff

Exponential backoff increases the delay between repeated connection attempts. Adding random jitter helps prevent many clients from reconnecting simultaneously after a shared outage.

For example, a client might use progressively longer delays such as 1, 2, 4, and 8 seconds, with a configured maximum and random variation.

12.3 Example Reconnection Hook

The following learning example retries a connection with capped exponential backoff. A production implementation should also consider network reachability, authentication refresh, application foreground state, heartbeat detection, and a limit on repeated attempts.

import { useEffect, useRef, useState } from 'react';

export default function useReconnectingWebSocket(url) {
  const socketRef = useRef(null);
  const retryTimerRef = useRef(null);
  const attemptRef = useRef(0);

  const [status, setStatus] = useState('connecting');

  useEffect(() => {
    let active = true;

    function connect() {
      if (!active) return;

      setStatus('connecting');

      const socket = new WebSocket(url);
      socketRef.current = socket;

      socket.onopen = () => {
        if (!active) return;

        attemptRef.current = 0;
        setStatus('connected');
      };

      socket.onmessage = event => {
        if (active) {
          console.log('Received:', event.data);
        }
      };

      socket.onerror = () => {
        if (active) {
          setStatus('error');
        }
      };

      socket.onclose = () => {
        if (!active) return;

        setStatus('disconnected');

        const attempt = attemptRef.current;
        const baseDelay = Math.min(
          1000 * (2 ** attempt),
          30000
        );
        const jitter = Math.random() * 500;

        attemptRef.current += 1;

        retryTimerRef.current = setTimeout(
          connect,
          baseDelay + jitter
        );
      };
    }

    connect();

    return () => {
      active = false;

      if (retryTimerRef.current) {
        clearTimeout(retryTimerRef.current);
      }

      const socket = socketRef.current;
      socketRef.current = null;

      if (socket) {
        socket.onopen = null;
        socket.onmessage = null;
        socket.onerror = null;
        socket.onclose = null;

        if (
          socket.readyState === WebSocket.OPEN ||
          socket.readyState === WebSocket.CONNECTING
        ) {
          socket.close();
        }
      }
    };
  }, [url]);

  return {
    status,
    socketRef,
  };
}

This example is intentionally minimal. It retries indefinitely while mounted, so production code should introduce a retry policy, network-awareness, and a way to stop retries for permanent failures. It also does not expose a message subscription API; add one if the screen needs to render received events.

12.4 Reconnection Best Practices

  • Use exponential backoff with jitter.
  • Set a reasonable maximum delay.
  • Avoid reconnecting after intentional logout or manual disconnection.
  • Refresh expired authentication credentials before retrying where appropriate.
  • Re-subscribe to required rooms or channels after reconnecting.
  • Retrieve missed events or synchronize state after reconnecting.
  • Prevent multiple simultaneous sockets for the same logical connection.
  • Display a clear connection status when it affects the user experience.

13. Heartbeats and Connection Health

A connection can appear open even when the network path is no longer functioning properly. A heartbeat mechanism helps detect stale connections and maintain awareness of connectivity.

13.1 Ping and Pong

At the WebSocket protocol level, ping and pong control frames are defined for connection health checks. Whether the client can send or observe these frames directly depends on the API and library. Many applications instead implement an application-level heartbeat using ordinary messages.

13.2 Application-Level Heartbeat Example

// Send an application-level heartbeat when the
// server's documented protocol supports this message.
const heartbeatId = setInterval(() => {
  if (socket.readyState === WebSocket.OPEN) {
    socket.send(JSON.stringify({
      type: 'heartbeat',
      sentAt: Date.now(),
    }));
  }
}, 30000);

// Clear the interval when the connection is disposed.
clearInterval(heartbeatId);

A client should not assume that sending a heartbeat proves the connection is healthy. A robust protocol should also process acknowledgements or heartbeat responses and apply a timeout policy.

14. Authentication and WebSocket Security

Real-time connections often provide access to private messages, account data, collaborative documents, or live location information. Security must be designed into the connection and message protocol.

14.1 Authentication Methods

  • Use an authentication mechanism supported by the WebSocket server.
  • Validate the user's identity during connection establishment or through a secure application-level authentication message.
  • Use short-lived credentials where appropriate and define a refresh strategy.
  • Avoid placing long-lived secret tokens in URL query strings because URLs may appear in logs.
  • Revoke or close connections when the user logs out or loses authorization.

Standard WebSocket constructors do not expose a general-purpose custom-header option in the same way as many HTTP clients. Choose an authentication method supported by the server and the React Native networking environment. Do not assume that a browser-specific authentication technique will work identically on every mobile platform.

14.2 Security Best Practices

  • Use wss:// in production.
  • Authenticate users and authorize each subscription and message.
  • Validate message types, lengths, fields, and data types.
  • Apply rate limits to messages and connection attempts.
  • Protect against unauthorized room or channel subscriptions.
  • Keep secrets out of source code, logs, and analytics events.
  • Set limits on message size and incoming event frequency.
  • Handle expired sessions and permission changes.
  • Close connections appropriately during logout.

15. App Lifecycle and Connection Management

Mobile applications move between foreground and background states. Depending on the operating system and application configuration, background execution may be limited and an open WebSocket may be suspended or disconnected.

15.1 Important Lifecycle Considerations

  • Decide whether the connection is required while the app is in the foreground.
  • Use React Native's AppState API when connection behavior depends on app activity.
  • Clean up listeners and timers when they are no longer needed.
  • Reconnect or synchronize data when the application becomes active again.
  • Use push notifications when users need alerts while the app is suspended or terminated.
  • Avoid opening a new connection every time a component renders.

15.2 Example AppState Handling

import { AppState } from 'react-native';

const subscription = AppState.addEventListener(
  'change',
  nextState => {
    if (nextState === 'active') {
      console.log('App is active; check connection status');
    } else {
      console.log('App is not in the foreground');
    }
  }
);

// Clean up when the owning component or service is disposed.
subscription.remove();

This example demonstrates lifecycle observation only. The actual connection policy should be implemented by the component or service that owns the socket. Do not blindly close a shared connection from an arbitrary screen.

16. Managing Real-Time State in React Native

Incoming socket events often need to update the user interface immediately. React state, reducers, context, or a state-management library can be used depending on the size of the application.

16.1 Updating State with Incoming Messages

import { useState } from 'react';

function useLiveMessages() {
  const [messages, setMessages] = useState([]);

  function addMessage(message) {
    setMessages(previous => [
      ...previous,
      message,
    ]);
  }

  return {
    messages,
    addMessage,
  };
}

16.2 Avoiding Unnecessary Re-Renders

  • Keep state focused on the data that the screen actually needs.
  • Use stable message identifiers for list rendering.
  • Consider FlatList for large message collections.
  • Limit stored message history when appropriate.
  • Batch related state changes when useful.
  • Use memoization only when it provides a measurable benefit.
  • Move connection management outside frequently re-rendering components.

16.3 Handling High Message Volume

Large amounts of incoming data can overwhelm a mobile device if every event causes expensive processing or an unbounded state update. The standard WebSocket API does not provide automatic backpressure for incoming messages. MDN WebSockets API guide.

For high-volume applications, consider message batching, server-side filtering, event throttling, pagination, bounded queues, and reducing the frequency of UI updates.

17. WebSocket Server Basics

A React Native WebSocket client needs a compatible server. The server establishes connections, authenticates users, receives messages, processes events, and sends updates to authorized clients.

17.1 Example Node.js WebSocket Server

The following example demonstrates a simple server using the popular ws package. It is for learning only and does not implement production authentication, authorization, persistence, or rate limiting.

// Install the server package:
// npm install ws

import { WebSocketServer, WebSocket } from 'ws';

const server = new WebSocketServer({
  port: 8080,
});

server.on('connection', socket => {
  console.log('Client connected');

  socket.send(JSON.stringify({
    type: 'welcome',
    message: 'Connected to the WebSocket server',
  }));

  socket.on('message', rawData => {
    let message;

    try {
      message = JSON.parse(rawData.toString());
    } catch {
      socket.send(JSON.stringify({
        type: 'error',
        message: 'Invalid JSON',
      }));
      return;
    }

    if (message.type === 'chat_message') {
      const response = {
        type: 'chat_message',
        text: String(message.text ?? ''),
        receivedAt: new Date().toISOString(),
      };

      if (socket.readyState === WebSocket.OPEN) {
        socket.send(JSON.stringify(response));
      }
    }
  });

  socket.on('close', () => {
    console.log('Client disconnected');
  });

  socket.on('error', error => {
    console.error('Socket error:', error.message);
  });
});

console.log('WebSocket server listening on port 8080');

The server echoes a simple chat event to the connected client. To support real conversations, implement user authentication, message persistence, conversation membership, server-assigned message IDs, delivery to other authorized participants, and operational monitoring.

17.2 Testing a Local Server from a Mobile Device

  • A simulator may use a platform-specific address to access the host machine.
  • A physical device generally needs a reachable IP address or hostname for the development computer.
  • Ensure the development firewall allows the required port.
  • Use an appropriate secure endpoint for production.
  • Never expose an unauthenticated development server publicly.

18. Testing and Debugging WebSocket Applications

Testing should cover the connection lifecycle, message processing, network failures, security, and UI updates.

18.1 Important Test Scenarios

  • Successful connection establishment.
  • Connection failure when the server is unavailable.
  • Sending a message while the socket is connecting.
  • Receiving valid and invalid JSON payloads.
  • Unexpected server disconnection.
  • Reconnection after network recovery.
  • Authentication failure or expired credentials.
  • Duplicate messages and out-of-order events.
  • Component unmounting and listener cleanup.
  • Application background and foreground transitions.
  • Large volumes of incoming messages.
  • Unauthorized subscriptions and malformed events.

18.2 Debugging Checklist

  1. Confirm that the WebSocket URL is correct.
  2. Check that the server supports the WebSocket protocol.
  3. Verify the handshake and server logs.
  4. Confirm that the connection reaches the open state.
  5. Check message formats on both client and server.
  6. Inspect network connectivity and TLS configuration.
  7. Verify authentication and access permissions.
  8. Check whether listeners and timers are being cleaned up.
  9. Test disconnection and reconnection scenarios.
  10. Confirm that duplicate connections are not being created.

19. Common Mistakes and Their Solutions

Mistake Problem Solution
Sending before the connection opens The send operation may fail. Check the socket's ready state.
Creating a socket on every render Causes repeated connections and duplicate events. Use an effect or a dedicated connection manager.
Ignoring cleanup Can leave listeners, timers, or sockets active. Clean up resources when their owner is disposed.
Not reconnecting after unexpected closure Live updates stop working. Implement a deliberate retry policy.
Reconnecting too aggressively Consumes battery and overloads the server. Use exponential backoff and jitter.
Trusting incoming messages Malformed data can break the application. Validate event types and payload structure.
Using unencrypted connections Communication may be exposed to interception. Use WSS in production.
Assuming sockets work indefinitely in the background Updates may be missed while the app is suspended. Resynchronize on foreground and use push notifications when needed.
Keeping unlimited messages in memory Can degrade performance. Use bounded state, pagination, and appropriate message storage.
Ignoring authorization on the server Users may access data they should not see. Authorize every subscription and sensitive action.

20. Practical Project: Build a Real-Time Chat Application

Project objective: Build a React Native chat interface that connects to a WebSocket server and displays incoming and outgoing messages.

20.1 Required Features

  • Connection status indicator.
  • Text input for composing messages.
  • Send button.
  • Real-time incoming messages.
  • Message timestamps and sender information.
  • Reconnection after unexpected network failure.
  • Input and message validation.
  • Clean listener and connection lifecycle management.

20.2 Suggested Folder Structure

src/
  components/
    ChatMessage.js
    ChatInput.js
    ConnectionStatus.js
  screens/
    ChatScreen.js
  hooks/
    useChat.js
    useWebSocket.js
  services/
    webSocketService.js
    chatService.js
  utils/
    validateMessage.js
    formatTimestamp.js
  constants/
    socketConfig.js

20.3 Implementation Steps

  1. Set up a WebSocket server that supports the required event format.
  2. Create a connection service for managing socket events.
  3. Build a custom hook to expose connection status and messages.
  4. Create reusable chat-message and chat-input components.
  5. Implement the chat screen and connect it to the hook.
  6. Add authentication and server-side conversation authorization.
  7. Implement reconnection and missed-message synchronization.
  8. Test connection failure, malformed messages, and duplicate events.
  9. Optimize message rendering and verify cleanup behavior.

20.4 Expected Learning Outcomes

After completing this project, you should be able to establish WebSocket connections, send and receive structured messages, connect socket events to React state, handle connection failures, and design a maintainable real-time communication feature.

21. Best Practices Checklist

  • Use WSS for production communication.
  • Keep socket management separate from UI components.
  • Check connection state before sending messages.
  • Validate incoming events and handle malformed payloads.
  • Use a clear and documented message protocol.
  • Implement reconnection with exponential backoff and jitter.
  • Clean up listeners, timers, and owned connections.
  • Handle application foreground and background transitions.
  • Authenticate users and authorize every sensitive action.
  • Synchronize missed events after reconnecting.
  • Limit message volume and avoid unbounded memory growth.
  • Use push notifications when delivery is needed while the app is suspended.
  • Test failures and security scenarios before deployment.

22. Interview Questions and Answers

Q1. What is a WebSocket?

Answer: WebSocket is a protocol that provides persistent, bidirectional communication between a client and a server over a single connection.

Q2. What is the difference between HTTP and WebSockets?

Answer: HTTP is commonly used for request-response communication. WebSockets maintain a connection through which both the client and server can send messages independently.

Q3. What are the main WebSocket events?

Answer: The main events are open, message, error, and close.

Q4. What is the difference between ws and wss?

Answer: ws:// is an unencrypted WebSocket connection, while wss:// uses TLS encryption and is the normal choice for production applications.

Q5. Why should WebSocket logic be placed in a service?

Answer: A service centralizes connection management, message handling, and cleanup, reducing duplication and keeping screens focused on UI behavior.

Q6. What is a custom WebSocket hook?

Answer: It is a custom React hook that connects socket events to component state and exposes information such as connection status, incoming messages, and send operations.

Q7. What is exponential backoff?

Answer: Exponential backoff increases the delay between repeated reconnection attempts, helping reduce unnecessary network traffic during outages.

Q8. Why is a heartbeat used?

Answer: A heartbeat helps detect stale connections and determine whether communication with the server is still functioning.

Q9. Can WebSockets replace push notifications?

Answer: No. WebSockets are useful while a connection is active, but mobile operating systems may suspend background connections. Push notifications are generally needed for reliable alerts when the app is not active.

Q10. How do you secure a WebSocket connection?

Answer: Use WSS, authenticate connections, authorize subscriptions and messages, validate payloads, apply rate limits, and protect credentials.

Q11. How should an application handle duplicate messages?

Answer: Use stable message identifiers, deduplicate incoming events, and ensure the backend handles retries safely.

Q12. What happens if the server disconnects unexpectedly?

Answer: The application should update its connection state, apply a controlled reconnection strategy, and synchronize any missed data when the connection returns.

23. Quick Revision Notes

  • Real-time communication: Exchanges information with minimal delay.
  • WebSocket: Enables persistent two-way communication.
  • WSS: Encrypts WebSocket communication using TLS.
  • Events: Open, message, error, and close.
  • JSON messages: Provide a structured format for application events.
  • WebSocket service: Centralizes connection management.
  • Custom hook: Connects socket events with React state.
  • Reconnection: Restores communication after unexpected disconnection.
  • Heartbeat: Helps monitor connection health.
  • Security: Requires authentication, authorization, validation, and encryption.
  • App lifecycle: Requires careful handling of background and foreground transitions.
  • Testing: Must cover network failures, duplicate messages, and invalid events.

24. Conclusion

WebSockets and real-time communication are important tools for building responsive React Native applications. They enable features such as live chat, collaborative experiences, notifications while connected, location tracking, and continuously updated dashboards.

A reliable implementation requires more than opening a connection. Developers should design a clear message protocol, manage connections through reusable services or hooks, validate incoming data, implement reconnection and lifecycle handling, protect user information, and synchronize state after interruptions.

For further learning, explore the React Native Training course at JustAcademy and register for a course demo.

25. Additional Learning Resources

whatsapp