Dart WebSocketTransformer tutorial shows how to handle WebSocket connections in Dart using the WebSocketTransformer class.
last modified April 4, 2025
The WebSocketTransformer class in Dart provides functionality to upgrade HTTP connections to WebSocket connections. It’s part of Dart’s dart:io library for server-side applications.
WebSocketTransformer handles the WebSocket handshake protocol and manages the connection upgrade process. It transforms HTTP requests into WebSocket connections when the client supports it.
WebSocketTransformer is a utility class that upgrades HTTP connections to WebSocket connections. It implements the WebSocket protocol handshake and connection management.
Key features include protocol negotiation, connection upgrading, and message stream transformation. It works with both server and client WebSocket connections.
This example shows a basic WebSocket server using WebSocketTransformer.
server.dart
import ‘dart:io’; import ‘dart:convert’;
void main() async { final server = await HttpServer.bind(’localhost’, 8080); print(‘Server running on ${server.address}:${server.port}’);
await for (var request in server) { if (WebSocketTransformer.isUpgradeRequest(request)) { var socket = await WebSocketTransformer.upgrade(request); socket.add(‘Hello from server!’);
socket.listen((message) {
print('Received: $message');
socket.add('Echo: $message');
});
} else {
request.response
..statusCode = HttpStatus.badRequest
..write('WebSocket upgrade required')
..close();
}
} }
We create an HTTP server that upgrades WebSocket requests. The transformer handles the protocol upgrade automatically. After upgrade, we can send and receive messages.
$ dart server.dart Server running on InternetAddress(‘127.0.0.1’, IPv4):8080
This example demonstrates handling multiple WebSocket connections.
server.dart
import ‘dart:io’; import ‘dart:async’;
void main() async { final server = await HttpServer.bind(’localhost’, 8080); var clients = <WebSocket>[];
await for (var request in server) { if (WebSocketTransformer.isUpgradeRequest(request)) { var socket = await WebSocketTransformer.upgrade(request); clients.add(socket); print(‘New client connected (${clients.length} total)’);
socket.listen((message) {
print('Broadcasting: $message');
for (var client in clients) {
if (client != socket) {
client.add('Client says: $message');
}
}
}, onDone: () {
clients.remove(socket);
print('Client disconnected (${clients.length} remaining)');
});
} else {
request.response
..statusCode = HttpStatus.badRequest
..write('WebSocket upgrade required')
..close();
}
} }
We maintain a list of connected clients and broadcast messages to all except the sender. The onDone callback handles client disconnections cleanly.
$ dart server.dart New client connected (1 total) New client connected (2 total) Broadcasting: Hello from client 1 Client disconnected (1 remaining)
This example shows custom protocol negotiation during WebSocket upgrade.
server.dart
import ‘dart:io’;
void main() async { final server = await HttpServer.bind(’localhost’, 8080);
await for (var request in server) { if (WebSocketTransformer.isUpgradeRequest(request)) { var protocols = request.headers[‘sec-websocket-protocol’];
if (protocols != null && protocols.any((p) => p == 'chat-v1')) {
var socket = await WebSocketTransformer.upgrade(
request,
protocol: 'chat-v1'
);
socket.add('Protocol chat-v1 accepted');
} else {
request.response
..statusCode = HttpStatus.badRequest
..write('chat-v1 protocol required')
..close();
}
} else {
request.response
..statusCode = HttpStatus.badRequest
..write('WebSocket upgrade required')
..close();
}
} }
We check for a specific protocol (‘chat-v1’) during the upgrade process. If the protocol isn’t supported, we reject the connection. This enables protocol versioning.
$ dart server.dart
This example demonstrates proper error handling in WebSocket connections.
server.dart
import ‘dart:io’;
void main() async { try { final server = await HttpServer.bind(’localhost’, 8080); print(‘Server started’);
await for (var request in server) {
try {
if (WebSocketTransformer.isUpgradeRequest(request)) {
var socket = await WebSocketTransformer.upgrade(request);
socket.handleError((error) {
print('WebSocket error: $error');
socket.close();
});
socket.listen((message) {
if (message is! String) {
throw FormatException('Only text messages supported');
}
print('Received: $message');
}, onDone: () => print('Connection closed'));
} else {
request.response
..statusCode = HttpStatus.badRequest
..write('WebSocket upgrade required')
..close();
}
} catch (e) {
print('Request handling error: $e');
request.response
..statusCode = HttpStatus.internalServerError
..close();
}
}
} catch (e) { print(‘Server error: $e’); } }
We implement multiple layers of error handling: server startup, request processing, and WebSocket communication. This makes the server more robust.
$ dart server.dart Server started Received: Hello WebSocket error: FormatException: Only text messages supported Connection closed
This example shows a WebSocket client connecting to our server.
client.dart
import ‘dart:io’;
void main() async { try { var socket = await WebSocket.connect(‘ws://localhost:8080’); print(‘Connected to server’);
socket.listen(
(message) => print('Server says: $message'),
onError: (error) => print('Error: $error'),
onDone: () => print('Disconnected from server')
);
// Send messages every second
var counter = 0;
Timer.periodic(Duration(seconds: 1), (_) {
socket.add('Message ${++counter}');
});
} catch (e) { print(‘Connection failed: $e’); } }
The client connects to our WebSocket server and listens for messages. It sends periodic messages to demonstrate two-way communication.
$ dart client.dart Connected to server Server says: Hello from server! Server says: Echo: Message 1 Server says: Echo: Message 2 Disconnected from server
Protocols: Always negotiate and validate protocols
Errors: Implement comprehensive error handling
Resources: Clean up resources on disconnect
Messages: Validate message types and content
Security: Implement authentication if needed
Dart WebSocketTransformer Documentation
This tutorial covered Dart’s WebSocketTransformer class with practical examples showing server implementation, client communication, and best practices for WebSocket applications.
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Dart tutorials.