Building a Real-Time Stock Dashboard in Flutter Using WebSockets

Building a Real-Time Stock Dashboard in Flutter Using WebSockets

TB

Teqani Blogs

Writer at Teqani

May 20, 20255 min read

In today’s fast-paced digital world, real-time data is crucial for applications like stock trading platforms, live sports updates, and chat applications. Flutter, with its robust framework, combined with WebSockets, offers an efficient way to handle real-time data streams. This article guides you through building such a dashboard.

Understanding WebSockets in Flutter

WebSockets provide a full-duplex communication channel over a single, long-lived connection, allowing for real-time data exchange between the client and server. Unlike traditional HTTP requests, WebSockets maintain an open connection, enabling instant data transfer without the overhead of repeated requests.

In Flutter, the web_socket_channel package facilitates WebSocket communication, making it straightforward to integrate real-time features into your applications.

Setting Up the Project

Follow these steps to set up your Flutter project for WebSocket integration:

  • Add Dependencies: In your pubspec.yaml, include the necessary packages:
dependencies:
 flutter:
 sdk: flutter
 web_socket_channel: ^2.3.0
 firebase_auth: ^4.5.0
 rxdart: ^0.27.4
  • Initialize Firebase: Ensure Firebase is set up in your project to handle authentication. Follow the official Firebase Flutter documentation for setup instructions.

Implementing Authentication

Before establishing a WebSocket connection, authenticate the user using Firebase Authentication. This ensures that only authorized users can access the real-time data.

import 'package:firebase_auth/firebase_auth.dart';

Future<String?> getAuthToken() async {
 User? user = FirebaseAuth.instance.currentUser;
 return await user?.getIdToken();
}

Creating a WebSocket Manager with Reconnection Logic

To manage the WebSocket connection efficiently, especially in scenarios with unstable network conditions, implement a WebSocket manager that handles reconnections using an exponential backoff strategy.

import 'dart:async';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:rxdart/rxdart.dart';

class WebSocketManager {
 final String url;
 final BehaviorSubject<String> _messageStream = BehaviorSubject<String>();
 WebSocketChannel? _channel;
 Timer? _reconnectTimer;
 int _retrySeconds = 1;

 WebSocketManager(this.url);

 Stream<String> get messages => _messageStream.stream;

 void connect() async {
 try {
 _channel = WebSocketChannel.connect(Uri.parse(url));
 _channel!.stream.listen(
 (message) {
 _messageStream.add(message);
 },
 onDone: _handleDisconnection,
 onError: (error) => _handleDisconnection(),
 );
 _retrySeconds = 1; // Reset on successful connection
 } catch (e) {
 _scheduleReconnect();
 }
 }

 void _handleDisconnection() {
 _channel = null;
 _scheduleReconnect();
 }

 void _scheduleReconnect() {
 if (_reconnectTimer != null && _reconnectTimer!.isActive) return;
 _reconnectTimer = Timer(Duration(seconds: _retrySeconds), () {
 connect();
 _retrySeconds = (_retrySeconds * 2).clamp(1, 64); // Exponential backoff
 });
 }

 void send(String message) {
 if (_channel != null) {
 _channel!.sink.add(message);
 }
 }

 void dispose() {
 _reconnectTimer?.cancel();
 _channel?.sink.close();
 _messageStream.close();
 }
}

Designing the Stock Dashboard UI

Create a responsive UI that displays real-time stock data. Utilize Flutter’s StreamBuilder to listen to the WebSocket stream and update the UI accordingly.

import 'package:flutter/material.dart';

class StockDashboard extends StatelessWidget {
 final WebSocketManager webSocketManager;

 StockDashboard({required this.webSocketManager});

 @override
 Widget build(BuildContext context) {
 return Scaffold(
 appBar: AppBar(
 title: Text('Real-Time Stock Dashboard'),
 ),
 body: StreamBuilder<String>(
 stream: webSocketManager.messages,
 builder: (context, snapshot) {
 if (snapshot.hasData) {
 // Parse the JSON data and build the UI
 // For simplicity, assuming the message is a plain string
 return Center(child: Text(snapshot.data!));
 } else if (snapshot.hasError) {
 return Center(child: Text('Error: ${snapshot.error}'));
 }
 return Center(child: CircularProgressIndicator());
 },
 ),
 );
 }
}

Bringing It All Together

In your main application, initialize Firebase, authenticate the user, and establish the WebSocket connection.

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

void main() async {
 WidgetsFlutterBinding.ensureInitialized();
 await Firebase.initializeApp();
 // Authenticate the user here
 runApp(MyApp());
}

class MyApp extends StatelessWidget {
 final WebSocketManager webSocketManager = WebSocketManager('wss://yourserver.com/socket');

 @override
 Widget build(BuildContext context) {
 webSocketManager.connect();
 return MaterialApp(
 home: StockDashboard(webSocketManager: webSocketManager),
 );
 }
}

Testing and Deployment

Testing: Simulate network interruptions to test the reconnection logic. Ensure that the UI updates correctly with incoming data.

Deployment: Use secure WebSocket connections (wss://) in production. Ensure that your server validates Firebase tokens to authenticate users.

Conclusion

Integrating WebSockets into your Flutter application enables real-time data communication, essential for applications like stock dashboards. By incorporating authentication and reconnection logic, you ensure a secure and robust user experience.

TB

Teqani Blogs

Verified
Writer at Teqani

Senior Software Engineer with 10 years of experience

May 20, 2025
Teqani Certified

All blogs are certified by our company and reviewed by our specialists
Issue Number: #10bfd674-1a18-4d23-91ea-f15b66c5157b