rsocket-js

repository·1.0.x-alpha·Indexed 20 days ago

https://github.com/rsocket/rsocket-js

A JavaScript implementation of the RSocket protocol providing Reactive Streams semantics over asynchronous, binary boundaries for Node.js and browser environments. It supports five symmetric interaction models: request/response, request/stream, fire-and-forget, event subscription, and channel. The project is distributed as a monorepo with specific packages for core functionality, TCP and WebSocket transports, and RxJS adapters.

Tokens
25.5K
Snippets
88
Records
104
Agent score
71%

What's inside rsocket-js

  1. What is RSocket and its interaction models

    1.0.x-alpha

    RSocket is an application protocol that provides Reactive Streams semantics over an asynchronous, binary boundary. It is designed for use in both browsers and Node.js.

    RSocket enables five symmetric interaction models via asynchronous message passing over a single connection:

    • request/response: A stream of exactly 1.
    • request/stream: A finite stream of many.
    • fire-and-forget: A message with no response.
    • event subscription: An infinite stream of many.
    • channel: Bi-directional streams.
  2. Create a browser-ready RSocket library with Webpack

    1.0.x-alpha

    To expose RSocket functionality globally in a browser, you can configure Webpack to build a library file. This allows you to access the exported functionality (such as creating RSocket connections via WebSocket) through a global variable (e.g., rsocket) in any HTML file that loads the built script.

    Key components in this pattern:

    • src/rsocket.js: The source code defining the RSocket connection logic and utility functions (like creating buffers).
    • webpack.config.js: The configuration that instructs Webpack to expose the source exports in the global scope.
    • index.html: The consumer file that loads the built rsocket.js and uses the global variable.
  3. Set up the Webpack Browser Bundle Example

    1.0.x-alpha

    This example demonstrates how to use Webpack to create a library that can be loaded in an HTML file or used in a browser context without requiring NPM or other bundling tools in the end-user environment. It involves building a library that exposes RSocket functionality via the WebSocket transport and a global variable.

    ### Run the server
    
    1. Open a terminal in the `simple/server` directory (one level up from this README).
    2. Install dependencies:
    ```bash
    npm install
    1. Run the server:
    npm run start

    Run the client

    1. Open a terminal in the browser-bundle folder.
    2. Install dependencies:
    npm install
    1. Run the NPM server script:
    npm run serve
    1. Open in browser: Visit http://localhost:9000.
  4. Install rsocket-js packages via npm

    1.0.x-alpha

    The rsocket-js project is a monorepo where individual packages are independently versioned and distributed via NPM. Depending on your transport layer (TCP, WebSocket) or integration needs (RxJS, GraphQL/Apollo), you should install only the specific packages required for your application.

    Note: The current branch contains a TypeScript rewrite and artifacts are considered UNSTABLE and subject to breaking changes. For stable 0.x.x versions, refer to the master branch.

    npm install rsocket-core
    # Or other specific packages such as:
    # npm install rsocket-messaging
    # npm install rsocket-tcp-client
    # npm install rsocket-websocket-client
    # npm install rsocket-adapter-rxjs
  5. Understand the Entry interface for composite metadata

    1.0.x-alpha

    When decoding composite metadata, each constituent part is returned as an Entry. There are three specific implementations of Entry depending on the MIME type:

    1. WellKnownMimeTypeEntry: Used when the MIME type is a recognized WellKnownMimeType. The mimeType property returns the string representation of the type.
    2. ExplicitMimeTimeEntry: Used for custom MIME types provided as strings. The mimeType property returns the custom string.
    3. ReservedMimeTypeEntry: Used when a MIME type ID is recognized as a reserved type but cannot be fully decoded. In this case, mimeType is undefined and the type property contains the numeric ID.
  6. Configure RSocket Resumption

    1.0.x-alpha

    Resumption allows a client to reconnect and resume a session after a connection loss. To enable this, include a resume object in your ServerConfig.

    When enabled, the server maintains a sessionStore of ResumableClientServerInputMultiplexerDemultiplexer instances indexed by the resumeToken. If a client sends a RESUME frame with a valid token, the server will attempt to restore the session.

    const config: ServerConfig = {
      transport: myTransport,
      acceptor: mySocketAcceptor,
      resume: {
        casheSize: 1024,
        sessionTimeout: 60000 // 60 seconds
      }
    };
  7. Implement subscriber interfaces for RSocket

    1.0.x-alpha

    To handle RSocket messages, you must implement one or more subscriber interfaces depending on the interaction model used:

    • OnNextSubscriber: Handles incoming data via onNext(payload: Payload, isComplete: boolean).
    • OnTerminalSubscriber: Handles the end of a stream via onError(error: Error) or onComplete().
    • OnExtensionSubscriber: Handles protocol extensions via onExtension(extendedType: number, content: Buffer | null | undefined, canBeIgnored: boolean).
    • Requestable: Used in streaming models to control flow via request(requestN: number).
  8. Configure RSocket Leases

    1.0.x-alpha

    Leases allow a client to request permission to send a certain number of requests to the server. To enable this in RSocketServer, provide a lease object in the ServerConfig.

    If lease is provided in the config, the server will reject any SETUP frames from clients that do not have the lease flag enabled. If the client does enable leases, the server will enforce the maxPendingRequests limit.

    const config: ServerConfig = {
      transport: myTransport,
      acceptor: mySocketAcceptor,
      lease: {
        maxPendingRequests: 100
      }
    };
  9. Understand RSocket Transport Abstractions

    1.0.x-alpha

    RSocket communication is built on a hierarchy of transport interfaces:

    • Outbound: The lowest level for sending single Frame objects.
    • Stream: An extension of Outbound that supports connecting and disconnecting specific RSocket streams.
    • DuplexConnection: Represents a full network connection, providing access to a Multiplexer & Demultiplexer.
    • Multiplexer & Demultiplexer: Handles the routing of frames between the single connection and multiple logical RSocket streams.
    • FrameHandler: The base interface for processing incoming frames and handling connection closure.
  10. Manage fragmented payloads with FragmentsHolder

    1.0.x-alpha

    When dealing with fragmented RSocket payloads, use the FragmentsHolder interface to track the state of incoming fragments. It maintains whether fragments are present and accumulates the data and metadata buffers as they arrive.

    FragmentsHolder properties:

    • hasFragments: boolean indicating if the payload is currently being reassembled.
    • data: The accumulated Buffer for the payload data.
    • metadata: The accumulated Buffer for the payload metadata.
    import { FragmentsHolder } from 'rsocket-core';
    
    const holder: FragmentsHolder = {
      hasFragments: false,
      data: undefined,
      metadata: undefined
    };
  11. Use RxJS responder functions in rsocket-adapter-rxjs

    1.0.x-alpha
    The rsocket-adapter-rxjs package provides responder functions that bridge RSocket request frames to RxJS Observable streams. These functions allow you to implement RSocket interaction models (Fire-and-Forget, Request-Response, Request-Stream, and Request-Channel) by providing a handler function that accepts data and returns an Observable.
  12. Configure RSocketConnector via ConnectorConfig

    1.0.x-alpha

    The RSocketConnector is used to establish an RSocket connection. It requires a ConnectorConfig object which defines the transport, setup parameters, and optional features like resumption, leasing, and fragmentation.

    Configuration Options

    setup

    Configures the initial RSocket SETUP frame:

    • payload: An optional Payload containing data and metadata.
    • dataMimeType: MIME type for data (defaults to application/octet-stream).
    • metadataMimeType: MIME type for metadata (defaults to application/octet-stream).
    • keepAlive: Keep-alive interval in milliseconds (defaults to 60000).
    • lifetime: Connection lifetime in milliseconds (defaults to 300000).

    transport (Required)

    An instance of ClientTransport used to establish the underlying connection.

    lease

    Enables RSocket Lease functionality:

    • maxPendingRequests: The maximum number of requests allowed before waiting for a lease (defaults to 256).

    resume

    Enables RSocket Resumption to recover from connection loss:

    • cacheSize: Size of the frame cache.
    • tokenGenerator: A function that returns a Buffer to be used as the resumption token.
    • reconnectFunction: An async function (attempt: number) => Promise<void> used to handle reconnection logic.

    fragmentation

    • maxOutboundFragmentSize: Maximum size for outbound fragments (defaults to 0).
    const config: ConnectorConfig = {
      transport: myTransport,
      setup: {
        dataMimeType: 'application/json',
        keepAlive: 30000
      },
      lease: {
        maxPendingRequests: 100
      },
      resume: {
        tokenGenerator: () => Buffer.from('my-token'),
        reconnectFunction: async (attempt) => {
          // logic to wait or retry
        }
      }
    };