signalr

Introduction

SignalR is a library for enabling low-latency, bidirectional, and event-based communication between clients and servers. It is built on top of the WebSocket protocol and provides additional guarantees, such as falling back to HTTP long polling or automatic reconnection.

Notes:

  • SignalR supports connections based on HTTP and HTTPS (TLS) protocols;
  • Supports multiple transport methods: WebSockets, Server-Sent Events, Long Polling;

Demonstration

avatar

Download and Installation

ohpm install @ohos/signalr

For more information on OpenHarmony ohpm environment configuration, please refer to How to install OpenHarmony ohpm packages.

X86 Emulator Configuration

Running Apps/Services on an Emulator.

Usage Instructions

Prerequisite: Configure Network Permissions

Before using this library, you need to configure network permissions in the entry/src/main/module.json5 file:

"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET",
    "reason": "$string:internet_permission_reason",
    "usedScene": {
      "abilities": ["EntryAbility"],
      "when": "inuse"
    }
  }
]

Steps

  1. Import the dependency library
import { HubConnectionBuilder, HubConnection, HubConnectionState, LogLevel, HttpTransportType, IHttpConnectionOptions, ISubscription } from '@ohos/signalr';
  1. Initialize the SignalR client
hubConnection: HubConnection | null = null;
  1. Set connection configuration and listen for events
// Create connection configuration
const connectionOptions: IHttpConnectionOptions = {
  headers: {
    'User-Agent': 'HarmonyOS-SignalR-Client/1.0'
  },
  skipNegotiation: false,
  transport: HttpTransportType.WebSockets // or other transport methods
};

// Create the connection
this.hubConnection = new HubConnectionBuilder()
  .withUrl('http://yourserver.com/yourhub', connectionOptions)
  .configureLogging(LogLevel.Debug)
  .withKeepAliveInterval(15000) // Keep-alive interval of 15 seconds
  .withAutomaticReconnect([0, 2000, 10000, 30000]) // Reconnection intervals
  .build();
  1. Connect to the server
await this.hubConnection.start();
  1. Set up listeners for user messages, joins, and leaves
// Listen for received messages
this.hubConnection.on('ReceiveMessage', (user: string, message: string) => {
  console.log(`${user}: ${message}`);
});

// Listen for user joins
this.hubConnection.on('UserJoined', (userName: string) => {
  console.log(`${userName} joined the chat room`);
});

// Listen for user leaves
this.hubConnection.on('UserLeft', (userName: string) => {
  console.log(`${userName} left the chat room`);
});
  1. Send a message to the server
await this.hubConnection.invoke('SendMessage', userName, message);
  1. Set up connection state listeners
// Connection closed event
this.hubConnection.onclose((error?: Error) => {
  if (error) {
    console.error('Connection closed unexpectedly:', error);
  } else {
    console.log('Connection closed normally');
  }
});

// Reconnection event
this.hubConnection.onreconnecting((error?: Error) => {
  console.log('Reconnecting...');
});

this.hubConnection.onreconnected((connectionId?: string) => {
  console.log('Reconnection successful:', connectionId);
});
  1. Close the server connection
await this.hubConnection.stop();
  1. Streaming Data Transfer
// Receive stream data
const streamResult = this.hubConnection.stream<number>('StreamData', 10);

const subscription = streamResult.subscribe({
  next: (item: number) => {
    console.log('Received stream data:', item);
  },
  error: (err: Error) => {
    console.error('Stream transmission error:', err);
  },
  complete: () => {
    console.log('Stream transmission complete');
  }
});

// Stop the stream transmission
subscription.dispose();
  1. Additional Notes
  • The sample code provides a complete chat application demo. You can modify it according to your own needs.

API Reference

  • Initialize the client
hubConnection: HubConnection = new HubConnectionBuilder()
  .withUrl(url, options)
  .build();
  • Configure connection URL and options
withUrl(url: string, options?: IHttpConnectionOptions): HubConnectionBuilder
  • Configure logging level
configureLogging(logLevel: LogLevel): HubConnectionBuilder
  • Set server timeout
withServerTimeout(milliseconds: number): HubConnectionBuilder
  • Set keep-alive interval
withKeepAliveInterval(milliseconds: number): HubConnectionBuilder
  • Configure automatic reconnection
withAutomaticReconnect(retryDelays?: number[]): HubConnectionBuilder
  • Start the connection
start(): Promise<void>
  • Stop the connection
stop(): Promise<void>
  • Get connection state
state: HubConnectionState
  • Register an event listener
on(methodName: string, newMethod: (...args: (string | number | boolean | object)[]) => void): void
  • Call a server method
invoke<T = object>(methodName: string, ...args: (string | number | boolean | object)[]): Promise<T>
  • Send a message (without waiting for a response)
send(methodName: string, ...args: (string | number | boolean | object)[]): Promise<void>
  • Subscribe to a stream
stream<T>(methodName: string, ...args: (string | number | boolean)[]): IStreamResult<T>
// Example: stream<number>('StreamData', 10)
  • Stream subscription management
interface ISubscription<T> {
  dispose(): void; // Unsubscribe from the stream
}
  • Listen for connection close
onclose(callback: (error?: Error) => void): void
  • Listen for reconnection
onreconnecting(callback: (error?: Error) => void): void
onreconnected(callback: (connectionId?: string) => void): void
  • Transport type enum
enum HttpTransportType {
  None = 0,
  WebSockets = 1,
  ServerSentEvents = 2,
  LongPolling = 4
}
  • Connection state enum
enum HubConnectionState {
  Disconnected = "Disconnected",
  Connecting = "Connecting", 
  Connected = "Connected",
  Disconnecting = "Disconnecting",
  Reconnecting = "Reconnecting"
}
  • Log level enum
enum LogLevel {
  Trace = 0,
  Debug = 1,
  Information = 2,
  Warning = 3,
  Error = 4,
  Critical = 5,
  None = 6
}

About Obfuscation

  • For code obfuscation, please refer to Introduction to Code Obfuscation
  • If you want to prevent the @ohos/signalr library from being obfuscated during the code obfuscation process, you need to add the corresponding exclusion rule in the obfuscation configuration file obfuscation-rules.txt:
-keep
./oh_modules/@ohos/signalr

Constraints and Limitations

Verified on the following versions:

  • IDE: DevEco Studio 5.1.0.849; SDK: API18 (5.1.0.125).
  • IDE: DevEco Studio 5.1.1.823; SDK: API19 (5.1.1.823).

Directory Structure

|---- signalr
|     |---- entry  # Sample code folder
|           |---- src # Demo source code directory
|                 |---- main # Main code
|                       |---- ets # ArkTS code
|                             |---- pages # Pages directory
|                                   |---- Index.ets # Main page (Chat Demo)
|     |---- library  # SignalR library
|           |---- src # Library source code directory
|                 |---- main # Main code
|                       |---- ets # ArkTS code
|                             |---- src # Core classes directory
|                                   |---- HubConnection.ts # Hub connection core class
|                                   |---- HubConnectionBuilder.ts # Connection builder
|                                   |---- index.ts # Exported interfaces
|                                   |---- HarmonyHttpClient.ts # HarmonyOS HTTP client
|                                   |---- HarmonyWebSocketTransport.ts # WebSocket transport
|     |---- README.md  # Installation and usage instructions

Contributing

If you encounter any issues during use, you can submit an Issue. We also welcome you to submit a PR to contribute to the project.

Open Source License

This project is based on the MIT LICENSE. Please feel free to enjoy and participate in open source.