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;
}