9

In Flutter, I wanna listen to websocket disconnect event, how to achieve that? The websocket connect will be drop when app goes to background, I still not found a method to let it continuesly running in background (does anyone have solution?), So I have to detect if a websocket connect is lost or something, so that I can re-connect when lost connection. Pls help if anyone knows how to achieve that.

Danny Tuppeny
  • 40,147
  • 24
  • 151
  • 275
Nicholas Jela
  • 2,540
  • 7
  • 24
  • 40

5 Answers5

20

You can find out if websocket is closed by implementing onDone callback. See the example below:

      _channel = IOWebSocketChannel.connect(
        'ws://yourserver.com:port',
      );

      ///
      /// Start listening to new notifications / messages
      ///
      _channel.stream.listen(
        (dynamic message) {
          debugPrint('message $message');
        },
        onDone: () {
          debugPrint('ws channel closed');
        },
        onError: (error) {
          debugPrint('ws error $error');
        },
      );

Hope that helps.

Angel Todorov
  • 1,443
  • 2
  • 19
  • 37
  • 1
    I am sorry, If I didnt understood. But how are you reconnecting, in the onDone() method you are just printing. – Aloysius Samuel Apr 15 '21 at 10:31
  • Actually, it reconnects automatically. The point of the above code is to allow you to take some actions based on the event. – Angel Todorov Apr 22 '21 at 10:43
  • 1
    @AngelTodorov It does not reconnect automatically for me. Could you show some code that auto reconnect? – dante May 08 '22 at 11:06
2

If your server closes the connection just use pinginterval like this

ws.pingInterval = const Duration(seconds: 5);

onDone should be called.

basic ping pong is enough.

Aklesh Singh
  • 917
  • 10
  • 12
1

Other answers around SO and the web suggest that you can't just keep sockets open in the background (which seems reasonable, you'd be keeping open network connections that may affect battery life). Depending on your use case, you might be better looking at Push Notifications or something that checks on a schedule.

Danny Tuppeny
  • 40,147
  • 24
  • 151
  • 275
0
   WebSocketChannel channel = WebSocketChannel.connect(uri );
    Stream stream = channel.stream;
    stream.listen((event) {
      print('Event from Stream: $event');
      
    },onError: (e){
      
      Future.delayed(Duration(seconds: 10)).then((value) {
        connectAndListen();
      },);
      
    },
    onDone: (() {
    
      Future.delayed(Duration(seconds: 10)).then((value) {
        connectAndListen();
      },);
    })
    );
Aditya Bansal
  • 13
  • 1
  • 4
0

I recommend you to use this multiplatform websocket package https://pub.dev/packages/websocket_universal , there you can even track all WS events happening (and even built-in ping measurment if you need any):

import 'package:websocket_universal/websocket_universal.dart';

/// Example works with Postman Echo server
void main() async {
  /// Postman echo ws server (you can use your own server URI)
  /// 'wss://ws.postman-echo.com/raw'
  /// For local server it could look like 'ws://127.0.0.1:42627/websocket'
  const websocketConnectionUri = 'wss://ws.postman-echo.com/raw';
  const textMessageToServer = 'Hello server!';
  const connectionOptions = SocketConnectionOptions(
    pingIntervalMs: 3000, // send Ping message every 3000 ms
    timeoutConnectionMs: 4000, // connection fail timeout after 4000 ms
    /// see ping/pong messages in [logEventStream] stream
    skipPingMessages: false,

    /// Set this attribute to `true` if do not need any ping/pong
    /// messages and ping measurement. Default is `false`
    pingRestrictionForce: false,
  );

  /// Example with simple text messages exchanges with server
  /// (not recommended for applications)
  /// [<String, String>] generic types mean that we receive [String] messages
  /// after deserialization and send [String] messages to server.
  final IMessageProcessor<String, String> textSocketProcessor =
      SocketSimpleTextProcessor();
  final textSocketHandler = IWebSocketHandler<String, String>.createClient(
    websocketConnectionUri, // Postman echo ws server
    textSocketProcessor,
    connectionOptions: connectionOptions,
  );

  // Listening to webSocket status changes
  textSocketHandler.socketHandlerStateStream.listen((stateEvent) {
    // ignore: avoid_print
    print('> status changed to ${stateEvent.status}');
  });

  // Listening to server responses:
  textSocketHandler.incomingMessagesStream.listen((inMsg) {
    // ignore: avoid_print
    print('> webSocket  got text message from server: "$inMsg" '
        '[ping: ${textSocketHandler.pingDelayMs}]');
  });

  // Listening to debug events inside webSocket
  textSocketHandler.logEventStream.listen((debugEvent) {
    // ignore: avoid_print
    print('> debug event: ${debugEvent.socketLogEventType}'
        ' [ping=${debugEvent.pingMs} ms]. Debug message=${debugEvent.message}');
  });

  // Listening to outgoing messages:
  textSocketHandler.outgoingMessagesStream.listen((inMsg) {
    // ignore: avoid_print
    print('> webSocket sent text message to   server: "$inMsg" '
        '[ping: ${textSocketHandler.pingDelayMs}]');
  });

  // Connecting to server:
  final isTextSocketConnected = await textSocketHandler.connect();
  if (!isTextSocketConnected) {
    // ignore: avoid_print
    print('Connection to [$websocketConnectionUri] failed for some reason!');
    return;
  }

  textSocketHandler.sendMessage(textMessageToServer);

  await Future<void>.delayed(const Duration(seconds: 30));
  // Disconnecting from server:
  await textSocketHandler.disconnect('manual disconnect');
  // Disposing webSocket:
  textSocketHandler.close();
}
Dmitrii Matunin
  • 275
  • 4
  • 5