A charming romance between WebSocket and React Native
Tags: websocket, android, ios, reactnative
Published: 2024-07-02 11:37:01

In modern mobile development, WebSockets offer a powerful way to enable real-time communication between the client and server. React Native, being a popular framework for building mobile applications, pairs excellently with WebSockets. In this blog, I'll guide you through creating a custom WebSocket integration in React Native that handles connection, reconnection, and error handling gracefully.


## Why Use WebSockets?

WebSockets provide a full-duplex communication channel over a single, long-lived connection. Unlike traditional HTTP requests, which are initiated by the client, WebSockets allow for bi-directional communication, making them ideal for real-time applications like chat apps, live notifications, and online gaming.

## Creating the Custom WebSocket Integration

To manage WebSocket connections in a React Native application, we'll create a custom hook called useWebSocket. This hook will handle:

- Establishing the WebSocket connection.
- Managing connection status.
- Handling incoming messages.
-Reconnecting on connection loss with an exponential backoff strategy.


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

const useWebSocket = (
  onMessage = () => {},
  onError = () => {},
  onClose = () => {}
) => {
  const [isWebSocketConnected, setWebSocketConnected] = useState(false);

  const ws = useRef(null);
  const reconnectIntervalRef = useRef(1000);

  const url = 'ws://echo.websocket.org'; // replace it with your URL

  const connectWebSocket = () => {
    try {
      // Create a WebSocket connection
      ws.current = new WebSocket(url);

      // WebSocket event listeners
      ws.current.onopen = () => {
        setWebSocketConnected(true);
        reconnectIntervalRef.current = 1000; // Reset reconnection interval on successful connection
      };

      ws.current.onmessage = (event) => {
        onMessage(event.data);
      };

      ws.current.onerror = (error) => {
        onError(error);
      };

      ws.current.onclose = (event) => {
        setWebSocketConnected(false);
        onClose(event);
        // Attempt to reconnect
        setTimeout(() => {
          reconnectIntervalRef.current = Math.min(
            reconnectIntervalRef.current * 2,
            30000
          ); // Exponential backoff, max 30 seconds
          connectWebSocket();
        }, reconnectIntervalRef.current);
      };
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    connectWebSocket();
    // Clean up WebSocket connection on component unmount
    return () => {
      if (ws.current) {
        ws.current.close();
      }
    };
  }, [url]);

  return isWebSocketConnected;
};

export default useWebSocket;

```

## How to Use the Hook

```
import React, { useState } from 'react';
import { View, Text, FlatList, SafeAreaView, StyleSheet } from 'react-native';
import useWebSocket from './useWebSocket';

const WebSocketComponent = () => {
  const [messages, setMessages] = useState([]);

  const handleOnMessage = (message) => {
    setMessages((prevMessages) => [...prevMessages, message]);
    if (message === 'callAPI') {
      // Call your API here
      console.log('API called');
    }
  };

  const handleOnError = (error) => {
    console.error('WebSocket error:', error);
  };

  const handleOnClose = (event) => {
    console.log('WebSocket closed:', event);
  };

  const isWebSocketConnected = useWebSocket(handleOnMessage, handleOnError, handleOnClose);

  return (
    <SafeAreaView style={styles.container}>
      <Text style={styles.status}>
        Status: {isWebSocketConnected ? 'Connected' : 'Disconnected'}
      </Text>
      <FlatList
        data={messages}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({ item }) => <Text style={styles.message}>{item}</Text>}
      />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  status: {
    fontSize: 18,
    marginBottom: 16,
  },
  message: {
    fontSize: 16,
    marginBottom: 8,
  },
});

export default WebSocketComponent;


```

## Testing the WebSocket Connection with WebSocketKing

To test the WebSocket connection, follow these steps:

**1. Go to WebSocketKing:** Visit [WebSocketKing](https://websocketking.com/).
**2. Paste your WebSocket URL:** Enter your WebSocket URL in the connection field.
**3. Press Connect:** Establish the connection by clicking the connect button.
**4. Send a Message:** In the payload field, type the message you want to send, e.g., callAPI.
**5. Press Send:** Send the message.

When the message callAPI is received, the handleOnMessage function will handle it and log "API called" to the console. You can replace this with an actual API call as needed.

## Conclusion

By using the useWebSocket hook, you can easily integrate WebSocket functionality into your React Native applications. This hook not only establishes and manages the WebSocket connection but also handles reconnections with an exponential backoff strategy, ensuring a robust and reliable real-time communication channel. Testing your WebSocket connection with WebSocketKing helps ensure that everything works as expected before deploying your application.

Feel free to customize the hook further based on your application's needs. Happy coding!