Skip to content

hashimsaffarini/dart_websocket_sample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🔌 dart_websocket_sample

A Dart CLI tool that makes WebSocket traffic visible — frame by frame.

Dart Tests License GSoC


🧩 The Problem

Flutter DevTools shows HTTP traffic beautifully:

GET  /api/users    ✅  200   45ms
POST /api/login    ✅  201  120ms

But when your app uses WebSocket? The Network panel shows nothing:

(empty — no visibility at all)

Developers debugging real-time apps are flying blind. 🙈


💡 The Solution

ProfileableWebSocket wraps dart:io's WebSocket and silently records every frame:

You type → ProfileableWebSocket → real WebSocket → server
                    ↓ records FrameEvent
Echo back ← ProfileableWebSocket ← real WebSocket ← server
                    ↓ records FrameEvent
               prints live table

This is the data model and interception layer needed to bring WebSocket visibility to Flutter DevTools — making it as observable as HTTP traffic is today.


✨ What This Sample Does

Feature Description
🎁 Wrapper ProfileableWebSocket wraps dart:io WebSocket transparently
📦 Recording Every frame captured with timestamp, direction, size, and type
🧪 Tested 5 unit tests against a real local echo server — no mocks
📟 Live Table CLI app displays a real-time traffic table in the terminal

🗂 Project Structure

dart_websocket_sample/
├── bin/
│   └── main.dart                         # CLI entry point
├── lib/
│   ├── profileable_websocket.dart        # WebSocket wrapper ← core
│   └── frame_event.dart                  # Frame data model
├── test/
│   └── profileable_websocket_test.dart   # 5 passing tests
└── pubspec.yaml

🚀 Getting Started

Requirements

  • Dart SDK >=3.0.0

Run

dart pub get
dart run bin/main.dart

Test

dart test

Analyze

dart format .
dart analyze

📟 Live Demo

Connecting to wss://echo.websocket.org ...
Connected. Type a message and press Enter. Ctrl+C to exit.

> Hello Dart!

─────────────────────────────────────────────────────────
 #   Time       Direction    Size     Type    Preview
─────────────────────────────────────────────────────────
 1   10:00:01   ↑ SENT       10 B    text    Hello Da...
 2   10:00:01   ↓ RECEIVED   10 B    text    Hello Da...
─────────────────────────────────────────────────────────

> WebSocket profiling is working!

─────────────────────────────────────────────────────────
 #   Time       Direction    Size     Type    Preview
─────────────────────────────────────────────────────────
 1   10:00:01   ↑ SENT       10 B    text    Hello Da...
 2   10:00:01   ↓ RECEIVED   10 B    text    Hello Da...
 3   10:00:05   ↑ SENT       27 B    text    WebSocke...
 4   10:00:05   ↓ RECEIVED   27 B    text    WebSocke...
─────────────────────────────────────────────────────────

🏗 Architecture

┌─────────────────────────────────────────┐
│              bin/main.dart              │  ← CLI loop + table printer
└────────────────────┬────────────────────┘
                     │ uses
┌────────────────────▼────────────────────┐
│        ProfileableWebSocket             │  ← intercepts every frame
│  ┌──────────────────────────────────┐   │
│  │   dart:io WebSocket (_inner)     │   │  ← real connection inside
│  └──────────────────────────────────┘   │
│  List<FrameEvent> events                │  ← growing log of frames
└────────────────────┬────────────────────┘
                     │ produces
┌────────────────────▼────────────────────┐
│             FrameEvent                  │  ← timestamp, direction,
│                                         │    size, type, data
└─────────────────────────────────────────┘

🔬 Design Notes

ProfileableWebSocket uses the Wrapper Pattern — it holds a reference to the real dart:io WebSocket internally and delegates all operations to it, while recording frame metadata before forwarding each frame.

Why a wrapper for the sample? The full GSoC implementation will instrument dart:io's WebSocket directly — similar to how HttpClient.enableTimelineLogging works — so all traffic is captured automatically without requiring a wrapper. The wrapper approach was chosen for this sample to keep it self-contained and easy to run. (Approach confirmed with mentor Samuel Rawlins.)


🔗 Related


Made with ❤️ for GSoC 2026 — Dart Organization

About

A Dart CLI sample demonstrating WebSocket frame profiling — built for GSoC 2026 (Dart organization)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages