---
title: "React Native · RUAL Documentation"
description: "Use RUAL with React Native."
canonical: https://docs.rual.nl/other/react-native
language: en
---

# React Native

You can integrate the RUAL backend with any frontend or application. The most commonly used framework is React Native, and we offer connection code that can serve as a template.

### Authentication

If you wish to manage authentication using RUAL, you can refer to our [authentication APIs](https://docs.rual.nl/cluster/api/authentication). These APIs enable you to generate a valid `access_token` that you can store locally on the device for future use.

### WebSocket Connection

The most commonly employed connection logic is WebSocket. Below, we offer an example code snippet for establishing such a connection, which is compatible with React Native.

```
export default class WS {
  requestId = 0;
  openRequests = new Map();
  _connection = null;

  connect () {
    if (this._connection) {
      if (this._connection.readyState === this._connection.CONNECTING || this._connection.readyState === this._connection.OPEN) {
        return;
      }
    }

    this.requestId = 0;
    this._connection = new WebSocket('wss://rual-ws.{{cluster-domain}}/primus');
    this._connection.onopen = () => {
      console.log('connected');
    };
    this._connection.onmessage = (e) => {
      this.handleMessage(e);
    };
    this._connection.onerror = (e) => {
      this.disconnect();
    };
    this._connection.onclose = (e) => {
      this.disconnect();
      this.handleClose(e);
    };
  }

  async waitForConnected (count = 0) {
    if (!this._connection) {
      this.connect();
    } else if (this._connection) {
      if (this._connection.readyState === this._connection.OPEN) {
        return;
      }
    }

    console.log('waiting for connection [' + count + ']');
    await (new Promise((resolve) => {
      setTimeout(resolve, 100 + (1 * count));
    }));

    return this.waitForConnected(count + 1);
  }

  disconnect () {
    if (this._connection) {
      try {
        this._connection.close();
      } catch (e) {}
    }
    this._connection = null;
  }

  async requestURI (method, uri, body = null, query = null, token = null) {
    await this.waitForConnected();

    this.requestId += 1;
    const uriId = 'RN' + String(this.requestId).padStart(10, '0');
    const requestBody = {
      'method': String(method).toUpperCase(),
      'requestid': uriId,
      'uri': '/api/' + uri
    };

    if (token) {
      requestBody.access_token = token;
    }

    if (body) {
      requestBody.body = body;
    }
    if (query) {
      requestBody.query = query;
    }

    this._connection.send(JSON.stringify(requestBody));
    return new Promise((resolve, reject) => {
      this.openRequests.set(uriId, {
        'resolve': resolve,
        'reject': reject,
        'uri': uri,
        'method': method
      });
    });
  }

  handleClose (message) {
    console.log(message);
    console.log('closed');
  }

  handleMessage (message) {
    if (message.data) {
      const data = JSON.parse(message.data);
      console.log('---> ', data);
      if (typeof data === 'string') {
        this._replyPing(message.data);
        return;
      }

      try {
        if (data.requestid) {
          const currentRequest = this.openRequests.get(data.requestid);
          if (currentRequest) {
            if (data.code === 200) {
              currentRequest.resolve(data.result);
            } else {
              currentRequest.reject(data.result);
            }

            this.openRequests.delete(data.requestid);
          } else {
            console.log('request id', data.requestid, 'not found');
          }
        }

        if (data.broadcast) {
          const payload = data.broadcast.message || {};
          switch (payload.type) {
            case 'broadcast-type':
              // do something with payload
              break;
          }
        }
      } catch (err) {
        console.error('failed handle WS');
      }
    }
  }

  async _replyPing (data) {
    await this.waitForConnected();
    console.log('sending', data.replace('ping', 'pong'));
    this._connection.send(data.replace('ping', 'pong'));
  }
}
```
