Flutter WebSocket通信插件websocket_universal的使用
Flutter WebSocket通信插件websocket_universal的使用
websocket_universal
是一个为Dart和Flutter设计的WebSocket客户端库,支持所有平台(web、移动、桌面)。它提供了一个易于使用的接口来处理WebSocket通信,并且包含了一些实用的功能,如自动重连、Ping延迟测量等。以下是关于如何使用这个插件的详细介绍。
快速开始
import 'package:websocket_universal/websocket_universal.dart';
void main() async {
final textSocketHandler = IWebSocketHandler<String, String>.createClient(
'wss://ws.postman-echo.com/raw', // Postman echo ws server
SocketSimpleTextProcessor(),
);
textSocketHandler.incomingMessagesStream.listen((inMsg) {
print('> webSocket got text message from server: "$inMsg" '
'[ping: ${textSocketHandler.pingDelayMs}]');
});
textSocketHandler.outgoingMessagesStream.listen((inMsg) {
print('> webSocket sent text message to server: "$inMsg" '
'[ping: ${textSocketHandler.pingDelayMs}]');
});
await textSocketHandler.connect();
textSocketHandler.sendMessage('Hello server!');
await Future<void>.delayed(const Duration(seconds: 4));
await textSocketHandler.disconnect('manual disconnect');
textSocketHandler.close();
}
示例1:简单的字符串消息交换
描述
此示例展示了如何与服务器进行简单的字符串消息交换。我们使用了Postman Echo Server作为示例服务器。
import 'package:websocket_universal/websocket_universal.dart';
void main() async {
const websocketConnectionUri = 'wss://ws.postman-echo.com/raw';
const textMessageToServer = 'Hello server!';
const connectionOptions = SocketConnectionOptions(
pingIntervalMs: 3000,
timeoutConnectionMs: 4000,
skipPingMessages: false,
);
final IMessageProcessor<String, String> textSocketProcessor =
SocketSimpleTextProcessor();
final textSocketHandler = IWebSocketHandler<String, String>.createClient(
websocketConnectionUri,
textSocketProcessor,
connectionOptions: connectionOptions,
);
textSocketHandler.socketHandlerStateStream.listen((stateEvent) {
print('> status changed to ${stateEvent.status}');
});
textSocketHandler.incomingMessagesStream.listen((inMsg) {
print('> webSocket got text message from server: "$inMsg" '
'[ping: ${textSocketHandler.pingDelayMs}]');
});
textSocketHandler.logEventStream.listen((debugEvent) {
print('> debug event: ${debugEvent.socketLogEventType}'
' [ping=${debugEvent.pingMs} ms]. Debug message=${debugEvent.message}');
});
textSocketHandler.outgoingMessagesStream.listen((inMsg) {
print('> webSocket sent text message to server: "$inMsg" '
'[ping: ${textSocketHandler.pingDelayMs}]');
});
final isTextSocketConnected = await textSocketHandler.connect();
if (!isTextSocketConnected) {
print('Connection to [$websocketConnectionUri] failed for some reason!');
return;
}
textSocketHandler.sendMessage(textMessageToServer);
await Future<void>.delayed(const Duration(seconds: 30));
await textSocketHandler.disconnect('manual disconnect');
textSocketHandler.close();
}
示例2:推荐的方式 - 使用类型化的消息
描述
在实际应用中,推荐使用类型化消息来确保数据的一致性和可读性。下面是一个使用 ISocketMessage
和 IMessageToServer
接口的例子。
import 'package:websocket_universal/websocket_universal.dart';
void main() async {
const websocketConnectionUri = 'wss://ws.postman-echo.com/raw';
const textMessageToServer = 'Hello server!';
const connectionOptions = SocketConnectionOptions(
pingIntervalMs: 3000,
timeoutConnectionMs: 4000,
skipPingMessages: false,
);
final IMessageProcessor<ISocketMessage<Object?>, IMessageToServer>
messageProcessor = SocketMessageProcessor();
final socketHandler =
IWebSocketHandler<ISocketMessage<Object?>, IMessageToServer>.createClient(
websocketConnectionUri,
messageProcessor,
connectionOptions: connectionOptions,
);
socketHandler.logEventStream.listen((debugEvent) {
print('> debug event: ${debugEvent.socketLogEventType}'
' ping=${debugEvent.pingMs} ms. Debug message=${debugEvent.message}');
});
socketHandler.socketStateStream.listen((stateEvent) {
print('> status changed to ${stateEvent.status}');
});
const messageTypeStr = '[ISocketMessage]';
socketHandler.incomingMessagesStream.listen((inMsg) {
print('> webSocket got $messageTypeStr: $inMsg');
});
socketHandler.outgoingMessagesStream.listen((inMsg) {
print('> webSocket sent $messageTypeStr: $inMsg');
});
final isConnected = await socketHandler.connect();
if (!isConnected) {
print('Connection to [$websocketConnectionUri] failed for some reason!');
return;
}
final outMsg = MessageToServerImpl.onlyHost(
host: 'test',
data: '{"payload": "$textMessageToServer"}',
error: null,
);
socketHandler.sendMessage(outMsg);
await Future<void>.delayed(const Duration(seconds: 8));
await socketHandler.disconnect('manual disconnect');
socketHandler.close();
}
示例3:处理字节消息
描述
当需要发送或接收字节数组时,可以使用 SocketSimpleBytesProcessor
来处理二进制数据。
import 'dart:convert';
import 'package:websocket_universal/websocket_universal.dart';
void main() async {
const websocketLocalExample = 'ws://127.0.0.1:42627/websocket';
const textMessageToServer = 'Hello server!';
const connectionOptions = SocketConnectionOptions(
pingIntervalMs: 3000,
timeoutConnectionMs: 4000,
skipPingMessages: false,
);
final IMessageProcessor<List<int>, List<int>> bytesSocketProcessor =
SocketSimpleBytesProcessor();
final bytesSocketHandler =
IWebSocketHandler<List<int>, List<int>>.createClient(
websocketLocalExample,
bytesSocketProcessor,
connectionOptions: connectionOptions,
);
bytesSocketHandler.logEventStream.listen((debugEvent) {
print('> debug event: ${debugEvent.socketLogEventType}'
' ping=${debugEvent.pingMs} ms. Debug message=${debugEvent.message}');
});
bytesSocketHandler.incomingMessagesStream.listen((inMsg) {
print('> webSocket got bytes message from server: "$inMsg"');
});
bytesSocketHandler.outgoingMessagesStream.listen((inMsg) {
print('> webSocket sent bytes message to server: "$inMsg"');
});
final isBytesSocketConnected = await bytesSocketHandler.connect();
if (!isBytesSocketConnected) {
print('Connection to [$websocketLocalExample] for bytesSocketHandler '
'failed for some reason!');
return;
}
final bytesMessage = utf8.encode(textMessageToServer);
bytesSocketHandler.sendMessage(bytesMessage);
await Future<void>.delayed(const Duration(seconds: 7));
await bytesSocketHandler.disconnect('manual disconnect');
bytesSocketHandler.close();
}
示例4:高级 ISocketMessage 处理 - 组合服务器响应
描述
此示例展示了如何创建更复杂的请求并处理来自服务器的组合响应。
import 'dart:convert';
import 'package:websocket_universal/websocket_universal.dart';
void main() async {
const websocketConnectionUri = 'wss://ws.postman-echo.com/raw';
const connectionOptions = SocketConnectionOptions(
pingIntervalMs: 3000,
timeoutConnectionMs: 4000,
skipPingMessages: false,
);
final IMessageProcessor<ISocketMessage<Object?>, IMessageToServer>
messageProcessor = SocketMessageProcessor();
final socketHandler =
IWebSocketHandler<ISocketMessage<Object?>, IMessageToServer>.createClient(
websocketConnectionUri,
messageProcessor,
connectionOptions: connectionOptions,
);
final ISocketManagerMiddleware middleware = SocketManagerMiddleware();
final IWebSocketRequestManager requestManager = WebSocketRequestManager(
middleware: middleware,
webSocketHandler: socketHandler,
);
final IWebSocketDataBridge dataBridge = WebSocketDataBridge(requestManager);
final isConnected = await socketHandler.connect();
if (!isConnected) {
print('Connection to [$websocketConnectionUri] failed for some reason!');
return;
}
final requestGame = MessageToServerImpl.duo(
host: TestDecoder.host,
topic1: CustomGameModel.topic1,
data: jsonEncode(
const CustomGameModel(
name: 'MakeWorld strategy',
playersAmount: 8,
),
),
error: null,
);
final socketRequest = SocketRequest(requestMessage: requestGame);
final result =
await dataBridge.singleRequestFull<CustomGameModel>(socketRequest);
print('Got result: ${result.data}');
final outMsgList = MessageToServerImpl.duo(
host: TestDecoder.host,
topic1: CustomGameModel.topic1List,
data: jsonEncode([
const CustomGameModel(
name: 'MakeWorld strategy',
playersAmount: 8,
),
const CustomGameModel(
name: 'New patch',
playersAmount: 4,
),
]),
error: null,
);
final socketRequestList = SocketRequest(requestMessage: outMsgList);
final listResult = await dataBridge
.singleRequestFull<List<CustomGameModel>>(socketRequestList);
print('Got list result: ${listResult.data}');
final topicSingle = SocketTopicImpl.duo(
host: TestDecoder.host,
topic1: CustomGameModel.topic1,
);
final topicList = SocketTopicImpl.duo(
host: TestDecoder.host,
topic1: CustomGameModel.topic1List,
);
final compositeRequest = SocketRequest(
requestMessage: requestGame,
responseTopics: {topicSingle, topicList},
);
final compositeTask = dataBridge.compositeRequest(compositeRequest);
dataBridge.requestData(socketRequestList);
final compositeResp = await compositeTask;
final responseOne = compositeResp.getData<CustomGameModel>();
final responseTwo = compositeResp.getData<List<CustomGameModel>>();
print('Got composite result. Answers = ${compositeResp.dataCached.length}'
'[$responseOne] and [$responseTwo]');
await socketHandler.disconnect('manual disconnect');
requestManager.close();
socketHandler.close();
}
通过以上几个示例,您可以了解如何使用 websocket_universal
插件来实现不同类型的WebSocket通信。根据您的需求选择合适的方式来处理消息,以确保应用程序的稳定性和高效性。
更多关于Flutter WebSocket通信插件websocket_universal的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter WebSocket通信插件websocket_universal的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter应用中使用websocket_universal
插件来实现WebSocket通信的代码示例。这个插件允许你通过WebSocket协议与服务器进行通信。
首先,确保你已经在pubspec.yaml
文件中添加了websocket_universal
依赖:
dependencies:
flutter:
sdk: flutter
websocket_universal: ^2.0.1 # 请注意版本号,根据实际情况调整
然后运行flutter pub get
来安装依赖。
接下来,你可以按照以下步骤在Flutter应用中使用WebSocket通信:
1. 导入必要的包
在你的Dart文件中导入websocket_universal
包:
import 'package:websocket_universal/websocket_universal.dart';
2. 创建WebSocket连接
你可以使用WebSocketUniversal
类来创建一个WebSocket连接。下面是一个简单的示例,展示了如何连接到WebSocket服务器、发送消息和接收消息。
import 'package:flutter/material.dart';
import 'package:websocket_universal/websocket_universal.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
WebSocketUniversal? _webSocket;
TextEditingController _controller = TextEditingController();
List<String> _messages = [];
@override
void initState() {
super.initState();
connectToWebSocket();
}
void connectToWebSocket() {
_webSocket = WebSocketUniversal(
Uri.parse('wss://your-websocket-server-url'), // 替换为你的WebSocket服务器URL
protocols: [],
headers: {},
);
_webSocket!.onOpen = (dynamic data) {
print('WebSocket connected');
_messages.add('Connected to WebSocket server');
setState(() {});
};
_webSocket!.onMessage = (dynamic data) {
print('Received message: ${data.toString()}');
_messages.add('Received: ${data.toString()}');
setState(() {});
};
_webSocket!.onClose = (dynamic data) {
print('WebSocket closed');
_messages.add('Disconnected from WebSocket server');
setState(() {});
};
_webSocket!.onError = (dynamic error) {
print('WebSocket error: $error');
_messages.add('Error: $error');
setState(() {});
};
_webSocket!.connect();
}
void sendMessage() {
if (_webSocket!.readyState == WebSocketReadyState.OPEN) {
_webSocket!.send(_controller.text);
_messages.add('Sent: ${_controller.text}');
_controller.clear();
setState(() {});
} else {
_messages.add('WebSocket is not open');
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('WebSocket Demo'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: _messages.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_messages[index]),
);
},
),
),
TextField(
controller: _controller,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Send Message',
),
),
ElevatedButton(
onPressed: sendMessage,
child: Text('Send'),
),
],
),
),
),
);
}
@override
void dispose() {
_webSocket?.close();
_controller.dispose();
super.dispose();
}
}
3. 运行应用
保存上述代码并运行你的Flutter应用。你应该能够看到一个简单的界面,允许你连接到WebSocket服务器、发送消息并接收服务器的响应。
注意事项
- 请确保WebSocket服务器的URL是正确的,并且服务器正在运行。
- 在生产环境中,请处理更多的错误情况和连接管理,例如重连逻辑。
- 根据需要调整WebSocket的头部信息和协议。
希望这个示例能帮助你理解如何在Flutter应用中使用websocket_universal
插件进行WebSocket通信。