Dart WebSocketTransformer
最后修改于 2025 年 4 月 4 日
Dart 中的 WebSocketTransformer 类提供了将 HTTP 连接升级到 WebSocket 连接的功能。它是 Dart dart:io 库中用于服务器端应用程序的一部分。
WebSocketTransformer 处理 WebSocket 握手协议并管理连接升级过程。当客户端支持时,它会将 HTTP 请求转换为 WebSocket 连接。
基本定义
WebSocketTransformer 是一个将 HTTP 连接升级到 WebSocket 连接的实用类。它实现了 WebSocket 协议的握手和连接管理。
主要功能包括协议协商、连接升级和消息流转换。它适用于服务器和客户端的 WebSocket 连接。
基本的 WebSocket 服务器
此示例展示了一个使用 WebSocketTransformer 的基本 WebSocket 服务器。
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();
}
}
}
我们创建了一个升级 WebSocket 请求的 HTTP 服务器。Transformer 会自动处理协议升级。升级后,我们可以发送和接收消息。
$ dart server.dart
Server running on InternetAddress('127.0.0.1', IPv4):8080
处理多个连接
此示例演示了如何处理多个 WebSocket 连接。
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();
}
}
}
我们维护一个已连接客户端的列表,并将消息广播给除发送者之外的所有客户端。onDone 回调可以干净地处理客户端断开连接。
$ dart server.dart New client connected (1 total) New client connected (2 total) Broadcasting: Hello from client 1 Client disconnected (1 remaining)
自定义协议协商
此示例展示了在 WebSocket 升级期间的自定义协议协商。
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();
}
}
}
我们在升级过程中检查特定的协议('chat-v1')。如果协议不支持,我们会拒绝连接。这实现了协议版本控制。
$ dart server.dart
错误处理
此示例演示了 WebSocket 连接中的正确错误处理。
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');
}
}
我们实现了多层错误处理:服务器启动、请求处理和 WebSocket 通信。这使得服务器更加健壮。
$ dart server.dart Server started Received: Hello WebSocket error: FormatException: Only text messages supported Connection closed
客户端 WebSocket
此示例展示了一个连接到我们服务器的 WebSocket 客户端。
import 'dart:io';
void main() async {
try {
var socket = await WebSocket.connect('ws://: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');
}
}
客户端连接到我们的 WebSocket 服务器并监听消息。它会定期发送消息以演示双向通信。
$ dart client.dart Connected to server Server says: Hello from server! Server says: Echo: Message 1 Server says: Echo: Message 2 Disconnected from server
最佳实践
- 协议:始终协商和验证协议
- 错误:实施全面的错误处理
- 资源:在断开连接时清理资源
- 消息:验证消息类型和内容
- 安全:如有需要,请实施身份验证
来源
本教程通过实际示例介绍了 Dart 的 WebSocketTransformer 类,展示了服务器实现、客户端通信以及 WebSocket 应用程序的最佳实践。
作者
列出 所有 Dart 教程。