socket_io_client_new 1.0.3 copy "socket_io_client_new: ^1.0.3" to clipboard
socket_io_client_new: ^1.0.3 copied to clipboard

A fixed fork of socket_io_client that resolves the port 0 issue. When Dart's Uri.parse() parses URLs without explicit ports, it returns port=0, causing WebSocket connections to fail. This package prop [...]

example/example.dart

// ignore_for_file: avoid_print

import 'dart:async';
import 'package:socket_io_client_new/socket_io_client_new.dart' as IO;

/// Basic Usage Example
void main() {
  // Dart client - simple connection
  IO.Socket socket = IO.io('http://localhost:3000');

  socket.onConnect((_) {
    print('connect');
    socket.emit('msg', 'test');
  });

  socket.on('event', (data) => print(data));
  socket.onDisconnect((_) => print('disconnect'));
  socket.on('fromServer', (data) => print(data));
}

/// Connect Manually Example
void connectManually() {
  IO.Socket socket = IO.io(
    'http://localhost:3000',
    IO.OptionBuilder()
        .setTransports(['websocket']) // for Flutter or Dart VM
        .disableAutoConnect() // disable auto-connection
        .setExtraHeaders({'foo': 'bar'}) // optional
        .build(),
  );
  socket.connect();
}

/// Emit with Acknowledgement Example
void emitWithAck() {
  IO.Socket socket = IO.io('http://localhost:3000');

  socket.onConnect((_) {
    print('connect');
    socket.emitWithAck('msg', 'init', ack: (data) {
      print('ack $data');
      if (data != null) {
        print('from server $data');
      } else {
        print('Null');
      }
    });
  });
}

/// Socket Connection Events Example
void connectionEvents() {
  IO.Socket socket = IO.io('http://localhost:3000');

  socket.onConnect((_) => print('connect'));
  socket.onConnectError((err) => print('connect_error: $err'));
  socket.onDisconnect((_) => print('disconnect'));
  socket.onError((err) => print('error: $err'));
  socket.onReconnect((_) => print('reconnect'));
  socket.onReconnectAttempt((attempt) => print('reconnect_attempt: $attempt'));
  socket.onReconnectFailed((_) => print('reconnect_failed'));
  socket.onReconnectError((err) => print('reconnect_error: $err'));
  socket.onPing((_) => print('ping'));
  socket.onPong((_) => print('pong'));
}

/// Acknowledge with Server Example
void acknowledgeWithServer() {
  IO.Socket socket = IO.io('http://localhost:3000');

  socket.on('eventName', (data) {
    final dataList = data as List;
    final ack = dataList.last as Function;
    ack(null);
  });
}

/// Update Extra Headers Example
void updateExtraHeaders() {
  IO.Socket socket = IO.io('http://localhost:3000');

  // Update the extra headers
  socket.io.options?['extraHeaders'] = {'foo': 'bar'};

  // Reconnect the socket manually
  socket.io
    ..disconnect()
    ..connect();
}

/// Flutter Usage Example
void flutterUsage() {
  IO.Socket socket = IO.io(
    'http://localhost:3000',
    IO.OptionBuilder()
        .setTransports(['websocket']) // Required for Flutter or Dart VM
        .setExtraHeaders({'foo': 'bar'}) // optional
        .build(),
  );

  socket.onConnect((_) {
    print('Connected');
  });
}

// =============================================================================
// Stream and StreamBuilder Pattern
// =============================================================================

/// STEP 1: Stream setup
class StreamSocket {
  final _socketResponse = StreamController<String>.broadcast();

  void Function(String) get addResponse => _socketResponse.sink.add;
  Stream<String> get getResponse => _socketResponse.stream;

  void dispose() {
    _socketResponse.close();
  }
}

StreamSocket streamSocket = StreamSocket();

/// STEP 2: Connect and listen
void connectAndListen() {
  IO.Socket socket = IO.io(
    'http://localhost:3000',
    IO.OptionBuilder().setTransports(['websocket']).build(),
  );

  socket.onConnect((_) {
    print('connect');
    socket.emit('msg', 'test');
  });

  // When event received, add data to stream
  socket.on('event', (data) => streamSocket.addResponse(data.toString()));
  socket.onDisconnect((_) => print('disconnect'));
}

// =============================================================================
// Socket Service Pattern (Singleton)
// =============================================================================

/// A service class for managing socket connections
class SocketService {
  static SocketService? _instance;
  IO.Socket? _socket;
  bool _isConnected = false;

  final _connectionController = StreamController<bool>.broadcast();
  Stream<bool> get connectionStream => _connectionController.stream;
  bool get isConnected => _isConnected;

  factory SocketService() {
    _instance ??= SocketService._internal();
    return _instance!;
  }

  SocketService._internal();

  void connect(String url, {Map<String, dynamic>? auth}) {
    if (_isConnected) return;

    final optionBuilder = IO.OptionBuilder()
        .setPath('/socket.io/')
        .setTransports(['polling', 'websocket'])
        .enableAutoConnect()
        .enableForceNew()
        .enableReconnection()
        .setReconnectionAttempts(5)
        .setReconnectionDelay(1000)
        .setReconnectionDelayMax(5000);

    if (auth != null) {
      optionBuilder.setAuth(auth);
    }

    _socket = IO.io(url, optionBuilder.build());
    _setupEventListeners();
    _socket!.connect();
  }

  void _setupEventListeners() {
    _socket!.onConnect((_) {
      _isConnected = true;
      _connectionController.add(true);
      print('Connected to server');
    });

    _socket!.onDisconnect((_) {
      _isConnected = false;
      _connectionController.add(false);
      print('Disconnected from server');
    });

    _socket!.onConnectError((error) {
      print('Connection error: $error');
    });

    _socket!.onReconnect((_) {
      print('Reconnected');
    });

    _socket!.onReconnectAttempt((attempt) {
      print('Reconnect attempt: $attempt');
    });
  }

  void emit(String event, dynamic data) {
    _socket?.emit(event, data);
  }

  void emitWithAck(String event, dynamic data, {Function(dynamic)? ack}) {
    _socket?.emitWithAck(event, data, ack: ack);
  }

  void on(String event, Function(dynamic) handler) {
    _socket?.on(event, handler);
  }

  void off(String event) {
    _socket?.off(event);
  }

  void disconnect() {
    _socket?.disconnect();
    _socket?.dispose();
    _socket = null;
    _isConnected = false;
  }

  void dispose() {
    disconnect();
    _connectionController.close();
  }
}

// =============================================================================
// Advanced: Socket Service with Multiple Stream Controllers
// =============================================================================

/// Advanced service with multiple event streams
class SocketIOService {
  static SocketIOService? _instance;
  IO.Socket? _socket;
  bool _isConnected = false;

  // Stream controllers for different event types
  final StreamController<Map<String, dynamic>> _dataStreamController =
      StreamController<Map<String, dynamic>>.broadcast();

  final StreamController<Map<String, dynamic>> _notificationController =
      StreamController<Map<String, dynamic>>.broadcast();

  final StreamController<bool> _connectionStateController =
      StreamController<bool>.broadcast();

  // Getters for streams
  Stream<Map<String, dynamic>> get dataStream => _dataStreamController.stream;
  Stream<Map<String, dynamic>> get notificationStream =>
      _notificationController.stream;
  Stream<bool> get connectionStateStream => _connectionStateController.stream;

  bool get isConnected => _isConnected;

  // Singleton pattern
  factory SocketIOService() {
    _instance ??= SocketIOService._internal();
    return _instance!;
  }

  SocketIOService._internal();

  Future<void> connect({String? userId}) async {
    if (_isConnected) return;

    _socket = IO.io(
      'http://localhost:3000',
      IO.OptionBuilder()
          .setPath('/socket.io/')
          .setTransports(['polling', 'websocket'])
          .enableAutoConnect()
          .enableForceNew()
          .enableReconnection()
          .setReconnectionAttempts(5)
          .build(),
    );

    _setupEventListeners();
    _socket!.connect();
  }

  void _setupEventListeners() {
    _socket!.onConnect((_) {
      _isConnected = true;
      _connectionStateController.add(true);
    });

    _socket!.onDisconnect((_) {
      _isConnected = false;
      _connectionStateController.add(false);
    });

    // Listen to custom events
    _socket!.on('data', (data) {
      _handleData(data);
    });

    _socket!.on('notification', (data) {
      _handleNotification(data);
    });
  }

  void _handleData(dynamic data) {
    if (data is Map) {
      _dataStreamController.add(Map<String, dynamic>.from(data));
    }
  }

  void _handleNotification(dynamic data) {
    if (data is Map) {
      _notificationController.add(Map<String, dynamic>.from(data));
    }
  }

  // Join a room
  void joinRoom(String roomId) {
    if (_isConnected) {
      _socket!.emit('join', roomId);
    }
  }

  // Send data to server
  void sendData(String event, Map<String, dynamic> data) {
    if (_isConnected) {
      _socket!.emit(event, data);
    }
  }

  void disconnect() {
    _socket?.disconnect();
    _socket?.dispose();
    _socket = null;
    _isConnected = false;
  }

  void dispose() {
    disconnect();
    _dataStreamController.close();
    _notificationController.close();
    _connectionStateController.close();
  }
}
0
likes
140
points
163
downloads

Publisher

unverified uploader

Weekly Downloads

A fixed fork of socket_io_client that resolves the port 0 issue. When Dart's Uri.parse() parses URLs without explicit ports, it returns port=0, causing WebSocket connections to fail. This package properly handles default ports.

Repository (GitHub)
View/report issues

Topics

#socket-io #websocket #realtime #networking

Documentation

API reference

License

MIT (license)

Dependencies

logging, socket_io_common, web

More

Packages that depend on socket_io_client_new