Flutter实时通信插件socket_io_client的使用
Flutter实时通信插件socket_io_client的使用
socket.io-client-dart简介
socket.io-client-dart
是JavaScript Node.js库Socket.io-client v2._ ~ v4._的Dart端口。它允许在Dart中使用Socket.IO进行实时双向通信。
版本信息
socket.io-client-dart | Socket.io Server |
---|---|
v0.9.* ~ v1.* |
v2.* |
v2.* |
v3.* ~ v4.6.* |
v3.* |
v4.7.* ~ v4.* |
使用方法
Dart服务器端示例
import 'package:socket_io/socket_io.dart';
main() {
// Dart server
var io = Server();
var nsp = io.of('/some');
nsp.on('connection', (client) {
print('connection /some');
client.on('msg', (data) {
print('data from /some => $data');
client.emit('fromServer', "ok 2");
});
});
io.on('connection', (client) {
print('connection default namespace');
client.on('msg', (data) {
print('data from default => $data');
client.emit('fromServer', "ok");
});
});
io.listen(3000);
}
Dart客户端示例
import 'package:socket_io_client/socket_io_client.dart' as IO;
main() {
// Dart client
IO.Socket socket = IO.io('http://localhost:3000');
socket.onConnect((_) {
print('connect');
socket.emit('msg', 'test');
});
socket.on('event', (data) => print(data));
socket.onDisconnect((_) => print('disconnect'));
socket.on('fromServer', (_) => print(_));
}
手动连接
要手动连接套接字,可以设置选项autoConnect: false
并调用.connect()
。
IO.Socket socket = IO.io('http://localhost:3000',
IO.OptionBuilder()
.setTransports(['websocket']) // for Flutter or Dart VM
.disableAutoConnect() // disable auto-connection
.setExtraHeaders({'foo': 'bar'}) // optional
.build()
);
socket.connect();
更新额外的头信息
IO.Socket socket = ... // Create socket.
socket.io.options['extraHeaders'] = {'foo': 'bar'}; // Update the extra headers.
socket.io..disconnect()..connect(); // Reconnect the socket manually.
带有确认的消息发送
IO.Socket socket = ... // Create socket.
socket.onConnect((_) {
print('connect');
socket.emitWithAck('msg', 'init', ack: (data) {
print('ack $data') ;
if (data != null) {
print('from server $data');
} else {
print("Null") ;
}
});
});
监听套接字连接事件
const List EVENTS = [
'connect',
'connect_error',
'disconnect',
'error',
'reconnect',
'reconnect_attempt',
'reconnect_failed',
'reconnect_error',
'ping',
'pong'
];
// Replace 'onConnect' with any of the above events.
socket.onConnect((_) {
print('connect');
});
确认从套接字服务器接收事件
socket.on('eventName', (data) {
final dataList = data as List;
final ack = dataList.last as Function;
ack(null);
});
Flutter中的使用
在Flutter环境中(非Flutter Web环境),仅支持dart:io
WebSocket
IO.Socket socket = IO.io('http://localhost:3000',
IO.OptionBuilder()
.setTransports(['websocket']) // for Flutter or Dart VM
.setExtraHeaders({'foo': 'bar'}) // optional
.build());
使用Stream和StreamBuilder
Stream设置
class StreamSocket{
final _socketResponse= StreamController<String>();
void Function(String) get addResponse => _socketResponse.sink.add;
Stream<String> get getResponse => _socketResponse.stream;
void dispose(){
_socketResponse.close();
}
}
StreamSocket streamSocket = StreamSocket();
连接并监听
void connectAndListen(){
IO.Socket socket = IO.io('http://localhost:3000',
IO.OptionBuilder()
.setTransports(['websocket']).build());
socket.onConnect((_) {
print('connect');
socket.emit('msg', 'test');
});
// 当从服务器接收到事件时,数据被添加到流中
socket.on('event', (data) => streamSocket.addResponse(data));
socket.onDisconnect((_) => print('disconnect'));
}
构建带有StreamBuilder的Widget
class BuildWithSocketStream extends StatelessWidget {
const BuildWithSocketStream({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: StreamBuilder(
stream: streamSocket.getResponse ,
builder: (BuildContext context, AsyncSnapshot<String> snapshot){
return Container(
child: Text(snapshot.data ?? ''),
);
},
),
);
}
}
排查问题
无法连接HTTPS服务器或自签名证书服务器
参照issue,可以使用以下代码:
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(MyApp());
}
iOS关闭Socket时出现内存泄漏问题
请使用socket.dispose()
而不是socket.close()
或socket.disconnect()
来解决iOS上的内存泄漏问题。
MacOS上连接失败
通过在macos/Runner/*.entitlements
文件中添加以下键:
<key>com.apple.security.network.client</key>
<true/>
Flutter中无法连接不安全的HTTP连接
默认情况下,iOS和Android禁用了HTTP连接。可以在Stack Overflow找到解决方案。
贡献者指南
如果你想要为项目做出贡献,可以fork这个仓库并向我们发送一个pull request。
感谢所有贡献者!
更多关于Flutter实时通信插件socket_io_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter实时通信插件socket_io_client的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter项目中,使用socket_io_client
插件可以实现实时通信功能。以下是一个简单的示例,展示了如何在Flutter中使用socket_io_client
插件进行Socket.IO通信。
1. 添加依赖
首先,在pubspec.yaml
文件中添加socket_io_client
的依赖:
dependencies:
flutter:
sdk: flutter
socket_io_client: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
2. 导入包
在你的Dart文件中导入socket_io_client
包:
import 'package:socket_io_client/socket_io_client.dart' as IO;
3. 建立Socket连接
创建一个Socket.IO客户端并连接到服务器:
class _MyAppState extends State<MyApp> {
late IO.Socket socket;
@override
void initState() {
super.initState();
// 配置Socket.IO选项(可选)
Map<String, dynamic> options = {
'transports': ['websocket'],
'autoConnect': false
};
// 初始化Socket.IO客户端
socket = IO.io('http://your-server-url:port', options);
// 连接到服务器
socket.connect();
// 监听连接事件
socket.on('connect', () {
print('Socket connected');
// 可以在这里发送消息给服务器
socket.emit('message', 'Hello from Flutter!');
});
// 监听服务器发送的事件
socket.on('event_name', (data) {
print('Received event: $data');
});
// 监听错误事件
socket.on('error', (err) {
print('Socket error: $err');
});
// 监听断开连接事件
socket.on('disconnect', () {
print('Socket disconnected');
});
}
@override
void dispose() {
// 断开连接
socket.disconnect();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Socket.IO Example'),
),
body: Center(
child: Text('Check the console for socket events.'),
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
4. 发送和接收消息
你可以通过socket.emit
方法发送消息给服务器,并通过socket.on
方法监听来自服务器的消息。
发送消息
socket.emit('message', 'Hello from Flutter!');
接收消息
socket.on('event_name', (data) {
print('Received event: $data');
});
注意事项
- 服务器配置:确保你的Socket.IO服务器正在运行,并且URL和端口号正确。
- 错误处理:在实际应用中,添加更多的错误处理和重连逻辑。
- 状态管理:如果你的应用比较复杂,建议使用Flutter的状态管理库(如Provider、Riverpod或MobX)来管理Socket连接的状态。
这个示例提供了一个基本的框架,你可以根据需要进行扩展和修改。