Successfully Connected WebSocket in Flutter Flow - Sharing My Code and Looking for Improvements

Hi everyone,

I've been working on connecting a WebSocket in Flutter Flow for the past few weeks, and I'm excited to share that I've finally managed to do it! Although the UI isn't my main focus right now, I wanted to share my approach and code with the community, especially for those who might be facing similar challenges.

I've created a custom action in Flutter Flow to handle the WebSocket connection. The code is still a work in progress and I'm continuously refining it, but I believe it might be helpful for others in its current state.

Key Points:

  • The action involves creating and managing a WebSocket connection.

  • I'm using an AppState variable named listWSData to store the data received from the WebSocket. This variable is set to a JSON string.

Here's the core part of my WebSocket handling code:

// Automatic FlutterFlow imports
import '/backend/schema/structs/index.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!

import 'dart:convert';
import 'package:web_socket_client/web_socket_client.dart';

Future<dynamic> websocket(BuildContext context, bool isOpen) async {
  WebSocket? socket; // Declare as nullable

  if (isOpen) {
    try {
      // Create a WebSocket client.
      socket = WebSocket(Uri.parse('wss://YOUR_ WS _here'));
      print('Attempting to connect to WebSocket');

      // Handle the connection state.
      socket.connection.listen((state) {
        if (state is Connected) {
          print('WebSocket connected');
          FFAppState().isWebSocketOpen = true;
        } else if (state is Disconnected) {
          print('WebSocket disconnected');
          FFAppState().isWebSocketOpen = false;
        }
        // Handle other states like reconnecting, etc.
      });

      // Listen to messages from the server.
      socket.messages.listen((message) {
        try {
          if (message is String) {
            // Process the JSON string
            final Map<String, dynamic> parsedJson = json.decode(message);
            final Map<String, dynamic> tickers = parsedJson['watchTickers'];
            List<Map<String, dynamic>> result = [];

            tickers.forEach((pairName, tickerData) {
              final Map<String, dynamic> tickerInfo = {
                'pairName': pairName,
                'lastPrice': tickerData['last'],
                'baseVolume': tickerData['baseVolume'],
                'quoteVolume': tickerData['quoteVolume'],
                'change': tickerData['change']
              };
              result.add(tickerInfo);
            });

            // Store the processed data directly as a list of maps in the app state
            FFAppState().listWSData = result;
            (context as Element).reassemble();

            print('Processed and stored WebSocket Data: result');
          } else {
            print('Received non-string message');
          }
        } catch (e) {
          print('Error handling the message: $e');
        }
      }, onDone: () {
        FFAppState().isWebSocketOpen = false;
        print('WebSocket connection closed by the server');
      }, onError: (error) {
        FFAppState().isWebSocketOpen = false;
        print('WebSocket error: $error');
      });
    } catch (e) {
      print('Error establishing a WebSocket connection: $e');
      FFAppState().isWebSocketOpen = false;
      return null; // Return null or handle the error as needed.
    }
  } else {
    // Close the WebSocket if it's open
    if (socket != null) {
      socket.close();
      FFAppState().isWebSocketOpen = false;
      print('WebSocket connection closed manually');
    }
  }

  // Return the socket instance
  return socket;
}
10
21 replies