liblsl_coordinator

A performance-focused Dart library for multi-layer LSL-based device coordination. This library provides a robust foundation for coordinating multiple devices in real-time applications using Lab Streaming Layer (LSL) with support for different communication layers.

Open file limit

Every LSL outlet, inlet and resolver holds several sockets. On macOS and Linux, liblsl raises the process's open-file limit when it is loaded, so sessions with many nodes and streams no longer run into Too many open files. If it warns that it could not (e.g. in a sandbox), raise the limit yourself with ulimit -n 4096 before starting the app. See the liblsl README for details.

Features

  • Multi-layer Architecture: Support for coordination, gaming, high-frequency, and custom stream layers
  • Automatic Coordinator Discovery: Devices automatically find existing coordinators or promote themselves
  • Protocol Configuration: Predefined and custom protocol configurations for different use cases
  • Pausable/Resumable Streams: Game and sensor streams can be paused and resumed as needed
  • Isolate-based Processing: Each layer runs in its own isolate for optimal performance
  • Flexible Stream Management: Support for irregular frequency coordination and regular high-frequency data streams
  • Self-promotion Logic: Automatic coordinator election when no coordinator is present

Architecture

The library implements a layered approach where:

  1. Coordination Layer: Always present, handles device discovery, role assignment, and protocol setup
  2. Data Layers: Optional layers for specific data types (game, sensors, etc.)
  3. Stream Management: Each layer has its own outlets and inlets managed in isolates
  4. Protocol System: Configurable protocols define which layers are active and their properties

Getting Started

dart pub add liblsl_coordinator

Usage

Every node runs the same code: it discovers the others over LSL, one of them is elected coordinator, and the rest join as participants.

import 'package:liblsl_coordinator/liblsl_coordinator.dart';
import 'package:liblsl_coordinator/transports/lsl.dart';

Future<void> main() async {
  final config = CoordinationConfig(
    name: 'my_experiment',
    sessionConfig: CoordinationSessionConfig(name: 'session_1', maxNodes: 4),
    topologyConfig: HierarchicalTopologyConfig(
      promotionStrategy: PromotionStrategyRandom(),
      maxNodes: 4,
    ),
    streamConfig: CoordinationStreamConfig(
      name: 'coordination',
      sampleRate: 50.0,
    ),
    transportConfig: LSLTransportConfig(coordinationFrequency: 50.0),
  );

  final session = PeerSession.create(
    config,
    thisNodeConfig: NodeConfigFactory().defaultConfig().copyWith(name: 'node_a'),
  );
  await session.initialize();
  await session.join();
  print(session.isCoordinator ? 'coordinator' : 'participant');

  // Messages between nodes...
  session.events.userCoordinationMessages.listen((m) => print(m));
  await session.sendUserMessage('hello', 'Hello from node_a', {});

  // ...and data streams (the coordinator creates and starts them).
  if (session.isCoordinator) {
    await session.createDataStream(
      DataStreamConfig(
        name: 'Samples',
        channels: 2,
        sampleRate: 100.0,
        dataType: StreamDataType.double64,
      ),
    );
    await session.startStream('Samples');
  }

  await session.dispose();
}

The transport is pluggable: the same session code runs over the in-memory transport from peer_coordinator (package:peer_coordinator/in_memory.dart, used by the example), or over WebRTC with webrtc_coordinator.

For more information, see the liblsl.dart repository.

Libraries

config
Moved to package:peer_coordinator/config.dart.
coordination
Moved to package:peer_coordinator/coordination.dart.
data
Moved to package:peer_coordinator/data.dart.
discovery
Moved to package:peer_coordinator/discovery.dart.
framework
Moved to package:peer_coordinator/framework.dart.
interfaces
Moved to package:peer_coordinator/interfaces.dart.
liblsl_coordinator
Device coordination over Lab Streaming Layer.
logging
Moved to package:peer_coordinator/logging.dart.
network
Moved to package:peer_coordinator/network.dart.
transports/lsl
transports/lsl/isolate/isolate_manager
transports/lsl/isolate/outlet_buffer_pool
transports/lsl/isolate/time_correction_schedule
transports/lsl/lsl_coordination
transports/lsl/lsl_discovery
transports/lsl/lsl_predicate_compiler
transports/lsl/lsl_resource
transports/lsl/lsl_stream
transports/lsl/lsl_transport