Flutter实时通信插件socket_io_client的使用

发布于 1周前 作者 phonegap100 来自 Flutter

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

1 回复

更多关于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');
});

注意事项

  1. 服务器配置:确保你的Socket.IO服务器正在运行,并且URL和端口号正确。
  2. 错误处理:在实际应用中,添加更多的错误处理和重连逻辑。
  3. 状态管理:如果你的应用比较复杂,建议使用Flutter的状态管理库(如Provider、Riverpod或MobX)来管理Socket连接的状态。

这个示例提供了一个基本的框架,你可以根据需要进行扩展和修改。

回到顶部