Skip to content

Latest commit

 

History

History
156 lines (100 loc) · 4.83 KB

File metadata and controls

156 lines (100 loc) · 4.83 KB

WebSockets (react-native-nitro-websockets)

High-performance WebSockets for React Native, built as a Nitro Module (libwebsockets + mbedTLS). This package lives alongside react-native-nitro-fetch in the same repo; HTTP stays in nitro-fetch, sockets in nitro-websockets.

Installation

Install three packages: the WebSocket module, Nitro Modules (required by all Nitro libraries), and react-native-nitro-text-decoder (a peer dependency of nitro-websockets — used to decode UTF-8 text frames on the JS side).

npm i react-native-nitro-websockets react-native-nitro-text-decoder react-native-nitro-modules

If you already use react-native-nitro-fetch, add the websockets and text-decoder packages; keep react-native-nitro-modules on a compatible version (see each package’s peerDependencies).

Then install native pods (iOS) and rebuild:

cd ios && pod install && cd ..
npx react-native run-ios   # or run-android

iOS: No additional setup required

NitroWebSocket API

The JS surface is a small class modeled after the browser WebSocket

Constructor

import { NitroWebSocket } from 'react-native-nitro-websockets'

const ws = new NitroWebSocket(url: string, protocols?: string | string[], headers?: Record<string, string>)
  • urlws: / wss: endpoint.
  • protocols — optional subprotocol string or list (Sec-WebSocket-Protocol).
  • headers — optional extra HTTP headers for the upgrade request (as supported by native).

Properties

  • readyState'CONNECTING' | 'OPEN' | 'CLOSING' | 'CLOSED'
  • url, protocol, bufferedAmount, extensions

Methods

  • send(data: string | ArrayBuffer) — text or binary.
  • close(code?: number, reason?: string) — default code 1000.

Events (assign like the browser API)

  • onopen: (() => void) | null
  • onmessage: ((e: WebSocketMessageEvent) => void) | null
    • e.data — string for text frames.
    • e.isBinarytrue for binary; then prefer e.binaryData (ArrayBuffer).
  • onerror: ((error: string) => void) | null
  • onclose: ((e: { code: number; reason: string }) => void) | null

Example (aligned with the example app)

const ws = new NitroWebSocket('wss://echo.websocket.org')

ws.onopen = () => console.log('open')
ws.onmessage = (e) => console.log('message', e.data, e.isBinary)
ws.onerror = (err) => console.error(err)
ws.onclose = (e) => console.log('closed', e.code, e.reason)

ws.send('hello')
ws.close(1000, 'bye')

Prewarm on next app launch

Prewarming starts the TLS/WebSocket handshake natively on startup (before JS runs), using URLs you enqueue from JavaScript. That uses the same NativeStorage queue as nitro-fetch (nitro_fetch_storage), so react-native-nitro-fetch must be installed for prewarm to work.

JS helpers

import {
  prewarmOnAppStart,
  removeFromPrewarmQueue,
  clearPrewarmQueue,
} from 'react-native-nitro-websockets'

// Queue or update an entry (deduped by URL)
prewarmOnAppStart('wss://api.example.com/ws', ['chat-v1'], {
  Authorization: 'Bearer …',
})

// Remove one URL from the queue
removeFromPrewarmQueue('wss://api.example.com/ws')

// Clear the entire queue
clearPrewarmQueue()

Optional second argument: subprotocols array. Optional third: headers for the upgrade request.

Android native hook

In Application.onCreate, before or after loadReactNative:

import com.margelo.nitro.nitrofetchwebsockets.NitroWebSocketAutoPrewarmer

override fun onCreate() {
  super.onCreate()
  NitroWebSocketAutoPrewarmer.prewarmOnStart(this)
  //
}

Auth on cold start

If prewarmed sockets need fresh headers, register token refresh with target: 'websocket' or 'all' using registerTokenRefresh from react-native-nitro-fetch (see the main README, Token refresh (cold start)).

import { registerTokenRefresh } from 'react-native-nitro-fetch'
import { prewarmOnAppStart, NitroWebSocket } from 'react-native-nitro-websockets'

const WSS = 'wss://api.example.com/live'

registerTokenRefresh({
  target: 'websocket',
  url: 'https://api.example.com/oauth/token',
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ grant_type: 'client_credentials' }),
  mappings: [
    { jsonPath: 'access_token', header: 'Authorization', valueTemplate: 'Bearer {{value}}' },
  ],
})

prewarmOnAppStart(WSS)

// Runtime connection (add your own token if you have it in JS)
const ws = new NitroWebSocket(WSS, undefined, { Authorization: 'Bearer …' })

Use target: 'all' if you share the same OAuth response for both prefetchOnAppStart queues and WebSocket prewarm.

See also