Flutter实时通信插件flutter_io_socket的使用

Flutter实时通信插件flutter_io_socket的使用

示例代码

STEP1: 添加依赖

pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter_io_socket: ^0.0.7

STEP2: 在小部件中添加代码

import 'package:flutter/material.dart';
import 'package:flutter_io_socket/flutter_io_socket.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Socket socket;

  [@override](/user/override)
  void initState() {
    super.initState();
    init();
  }

  void init() {
    socket = io('http://localhost:3000',
        <String, dynamic>{
          'transports': ['websocket'],
          'autoConnect': false,
        });

    socket.connect();

    connectAndListen();
  }

  void connectAndListen() {
    socket.onConnect((_) => print('connect'));
    socket.onDisconnect((_) => print('disconnect'));
    socket.onError((_) => print('error'));
    socket.onConnecting((_) => print('connecting'));
    socket.onConnectError((_) => print('connect Error'));
    socket.onConnectTimeout((data) => print('timeout'));
    socket.on('connect_error', (value) => print('connect error ${value.toString()}'));

    // 当服务器发送事件时,将数据添加到流中
    socket.on('event', (data) => streamSocket.addResponse);

    // 发送消息
    Map<String, dynamic> map = new Map<String, dynamic>();
    map["message"] = "Hello";
    socket.emit('sendMessage', map);
  }

  [@override](/user/override)
  void dispose() {
    disposeSocket();
    super.dispose();
  }

  void disposeSocket() {
    socket.close();
    socket.dispose();
  }
}

// 使用Stream和StreamBuilder构建UI

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',
      OptionBuilder()
          .setTransports(['websocket'])
          .build());

  socket.onConnect((_) {
    print('connect');
    socket.emit('msg', 'test');
  });

  // 当服务器发送事件时,将数据添加到流中
  socket.on('event', (data) => streamSocket.addResponse);
  socket.onDisconnect((_) => print('disconnect'));
}

class BuildWithSocketStream extends StatelessWidget {
  const BuildWithSocketStream({Key key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      child: StreamBuilder(
        stream: streamSocket.getResponse,
        builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
          return Container(
            child: snapshot.hasData ? Text(snapshot.data) : Text('No data'),
          );
        },
      ),
    );
  }
}

手动连接

要手动连接套接字,设置选项 autoConnect: false 并调用 .connect()

例如,

Socket socket = io('http://localhost:3000',
    OptionBuilder()
      .setTransports(['websocket']) // 适用于 Flutter 或 Dart VM
      .disableAutoConnect()  // 禁用自动连接
      .setExtraHeaders({'foo': 'bar'}) // 可选
      .build()
  );
socket.connect();

注意,如果 autoConnect: true(默认情况下为 true),则不应调用 .connect(),否则所有事件处理程序将会被注册/触发两次。

更新额外头信息

Socket socket = ... // 创建套接字。
socket.io.options['extraHeaders'] = {'foo': 'bar'}; // 更新额外头信息。
socket.io.disconnect().connect(); // 手动重新连接套接字。

带确认的发射

Socket 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',
  'connect_timeout',
  'connecting',
  'disconnect',
  'error',
  'reconnect',
  'reconnect_attempt',
  'reconnect_failed',
  'reconnect_error',
  'reconnecting',
  'ping',
  'pong'
];

// 替换 'onConnect' 为上述事件中的任何一个。
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,而不是 dart:html WebSocket 或 Ajax (XHR),因此在这种情况下需要添加 setTransports(['websocket']) 当创建套接字实例时。

例如,

IO.Socket socket = IO.io('http://localhost:3000',
  OptionBuilder()
      .setTransports(['websocket']) // 适用于 Flutter 或 Dart VM
      .setExtraHeaders({'foo': 'bar'}) // 可选
      .build());

使用 Stream 和 StreamBuilder 在 Flutter 中

import 'dart:async';

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',
      OptionBuilder()
       .setTransports(['websocket']).build());

    socket.onConnect((_) {
     print('connect');
     socket.emit('msg', 'test');
    });

    // 当服务器发送事件时,将数据添加到流中
    socket.on('event', (data) => streamSocket.addResponse);
    socket.onDisconnect((_) => print('disconnect'));
}

class BuildWithSocketStream extends StatelessWidget {
  const BuildWithSocketStream({Key key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Container(
      child: StreamBuilder(
        stream: streamSocket.getResponse,
        builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
          return Container(
            child: snapshot.hasData ? Text(snapshot.data) : Text('No data'),
          );
        },
      ),
    );
  }
}

故障排除

无法连接到 HTTPS 服务器或自签名证书服务器

class MyHttpOverrides extends HttpOverrides {
  [@override](/user/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());
}

更多关于Flutter实时通信插件flutter_io_socket的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter实时通信插件flutter_io_socket的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用flutter_io_socket插件实现实时通信的示例代码。这个插件允许你通过WebSocket与服务器进行通信。

首先,确保你已经在pubspec.yaml文件中添加了flutter_io_socket依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_io_socket: ^0.1.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们将展示如何使用这个插件来建立WebSocket连接、发送和接收消息。

1. 导入插件

在你的Dart文件中导入flutter_io_socket

import 'package:flutter_io_socket/flutter_io_socket.dart';

2. 建立WebSocket连接

创建一个IO实例并连接到服务器:

class _MyAppState extends State<MyApp> {
  IO socket;

  @override
  void initState() {
    super.initState();
    
    // 替换为你的WebSocket服务器URL
    String serverUrl = 'http://your-websocket-server-url:port';
    
    socket = IO(serverUrl, <String, dynamic>{
      'transports': ['websocket'],
      'autoConnect': false
    });

    // 监听连接事件
    socket.onConnect((data) {
      print('Connected to server');
      // 连接成功后可以发送消息
      socket.emit('message', 'Hello from Flutter');
    });

    // 监听连接断开事件
    socket.onDisconnect((data) {
      print('Disconnected from server');
    });

    // 监听错误事件
    socket.onError((data) {
      print('Error: $data');
    });

    // 监听来自服务器的消息
    socket.on('message', (data) {
      print('Received message: $data');
    });

    // 手动连接
    socket.connect();
  }

  @override
  void dispose() {
    socket.disconnect();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter IO Socket Example'),
        ),
        body: Center(
          child: Text('Check the console for WebSocket messages'),
        ),
      ),
    );
  }
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

void main() {
  runApp(MyApp());
}

3. 解释代码

  • 创建IO实例:我们使用IO类创建一个WebSocket客户端实例,并传入服务器URL和配置选项。这里我们禁用了自动连接(autoConnect: false),以便手动控制连接过程。
  • 监听事件:通过onConnectonDisconnectonError和自定义事件(如on('message'))监听连接状态、错误和来自服务器的消息。
  • 连接和断开:在initState方法中调用socket.connect()手动连接到服务器,在dispose方法中调用socket.disconnect()确保在组件销毁时断开连接。

注意事项

  • 确保WebSocket服务器正在运行,并且URL正确无误。
  • 根据需要调整事件处理逻辑,如处理不同的消息类型或执行其他操作。
  • 在生产环境中,考虑添加更多的错误处理和重连逻辑以提高应用的健壮性。

这个示例展示了如何使用flutter_io_socket插件在Flutter应用中实现基本的WebSocket通信。根据具体需求,你可以进一步扩展和优化代码。

回到顶部