Flutter即时通讯插件flutter_mqchat的使用

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

Flutter即时通讯插件flutter_mqchat的使用

特性

使用MQTT作为聊天协议,创建一个支持所有所需功能的现代聊天应用程序。这是一个基于Flutter的MqChat客户端。

  • 登录
  • 发送/接收消息(文本、图像、视频、位置、文档、联系人消息)
  • 发送文件
  • 打字指示器
  • 在线状态
  • 群聊
  • 私聊邀请

开始使用

安装flutter-mqchat包:

flutter pub add flutter-mqchat

使用方法

完整的示例可以在这里找到。

1. 登录

用户使用现有账户登录:

bool connected = await ChatApp.instance()!.clientHandler.connect(
        host: "broker.url.com",
        username: "user@test.com",
        password: "user_pass");

成功登录后,MQTT客户端将收到更新。首先接收到的是个人资料详情、用户所属的房间、正在进行的邀请和消息(如果消息归档由代理支持)。

2. 监听我的个人资料更改
ChatApp.instance()!.archiveHandler.getUser().listen((user) {
      // 插入或更新用户到数据库
    });
3. 监听房间

当登录用户被添加到一个房间(或房间详细信息更改)时,房间详细信息将被添加到对话流中。

ChatApp.instance()!.archiveHandler.getAllConversations().listen((rooms) {
      // 插入或更新房间到数据库
    });
4. 监听新消息
ChatApp.instance()!.messageReader.getChatMessages().listen((message) {
      var dbMessage = message.toDbMessage();
      // 将消息插入到数据库
      // 如果消息不是我发送的,则发送聊天标记
    });
5. 监听聊天标记
ChatApp.instance()!
        .messageReader
        .getChatMarkerMessages()
        .listen((markerMessage) {

      String messageId = markerMessage.referenceId;
      if (markerMessage.status == ChatMarker.displayed) {
          // 更新数据库记录
      } else if (markerMessage.status == ChatMarker.delivered) {
          // 更新数据库记录
      }
    });
6. 监听新的聊天邀请
ChatApp.instance()!
        .invitationHandler
        .newInvitationsStream()
        .listen((invitation) {
          if(invitation.type == MessageType.EventInvitationRequest) {
            // 新的邀请请求
            // 将邀请记录插入到数据库,并通知用户
          }
          if(invitation.type == MessageType.EventInvitationResponseAccept || invitation.type == MessageType.EventInvitationResponseReject) {
            // 对邀请作出回应,更新本地记录并等待服务器同步新的联系人(如果接受)
            // 不要插入房间,用户会通过getAllConversations()接收到新的房间详细信息
          }
    });
7. 监听邀请更新

我们使用它来监听用户已发送的邀请。它可以是:

  • Info: 当收到确认邀请已发送的信息
  • Error: 当有错误(如用户未找到)
ChatApp.instance()!
        .invitationHandler
        .invitationUpdatesStream()
        .listen((invitation) {
      if (invitation.invitationMessageType == InvitationMessageType.INFO) {
       // 更新邀请记录为已确认
      }
      else if (invitation.invitationMessageType == InvitationMessageType.ERROR) {
        // 通知用户,并删除已插入的记录
      }
    });
8. 发送文本消息
ChatMessage newMessage = ChatMessage(
        id: "generated_random_id",
        type: MessageType.ChatText,
        text: "Hello there",
        roomId: "[room_id]",
        fromId: "[my_id]",//可选
        sendTime: DateTime.now().millisecondsSinceEpoch,
        fromName: "[my_name]");
8.1 发送常规消息
ChatApp.instance()!
          .messageSender
          .sendChatMessage(newMessage, "[room_id]");
8.2 发送回复消息
ChatMessage replyToMessage = ...; // 要回复的消息
ChatApp.instance()!
          .messageSender
          .replyToMessage(replyToMessage, newMessage, widget.contactChat.roomId);
9. 发送文件消息
 ChatApp.instance()!.messageSender.sendFileChatMessage(
          type: MessageType.ChatImage,//例如
          fileLocalPath: path,
          room: "[room_id]");
10. 发送打字指示器
ChatApp.instance()!
          .eventsSender
          .sendIsTyping(true, "[room_id]");
11. 监听打字指示器
ChatApp.instance()!.messageReader.getTypingMessages().listen((event) {
    // 使用event.roomId和event.isTyping和event.fromId,更新UI状态
    });
12. 发送新的聊天邀请
ChatApp.instance()!
        .eventsSender
        .sendInvitation("[invitee_username]", "[invitation_random_id]");

额外信息

TODO: 告诉用户更多关于包的信息:在哪里可以找到更多信息,如何为包做出贡献,如何提交问题,他们可以从包作者那里期望什么响应,等等。


完整示例代码

import 'package:example/mqtt_db_bridge/app_data.dart';
import 'package:example/providers/user_provider.dart';
import 'package:example/ui/screens/splash_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mqchat/chat_app.dart';
import 'package:flutter_mqchat/models/enums.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(const ProviderScope(child: MyApp()));
}

class MyApp extends ConsumerStatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  ConsumerState<MyApp> createState() => _MyAppState();
}

class _MyAppState extends ConsumerState<MyApp> with WidgetsBindingObserver {
  [@override](/user/override)
  void initState() {
    WidgetsFlutterBinding.ensureInitialized();
    WidgetsBinding.instance!.addObserver(this);
    AppData();

    super.initState();
  }

  [@override](/user/override)
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    super.dispose();
  }

  [@override](/user/override)
  void didChangeAppLifecycleState(AppLifecycleState state) {
    final user = ref.watch(userProvider);
    if (user.user != null) {
      if (state == AppLifecycleState.inactive ||
          state == AppLifecycleState.paused) {
        ChatApp.instance()!
            .eventsSender
            .sendPresence(PresenceType.away, user.user!.id);
      } else if (state == AppLifecycleState.resumed) {
        ChatApp.instance()!
            .eventsSender
            .sendPresence(PresenceType.available, user.user!.id);
      }
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter MqChat Client',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SplashScreen(),
    );
  }
}

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

1 回复

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


当然,以下是一个关于如何使用Flutter即时通讯插件 flutter_mqchat 的代码示例。请注意,flutter_mqchat 并非一个广为人知的官方或广泛使用的Flutter插件,因此以下示例假设它有一个类似于其他即时通讯插件的API设计。如果 flutter_mqchat 实际上存在但API不同,请查阅其官方文档进行调整。

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

dependencies:
  flutter:
    sdk: flutter
  flutter_mqchat: ^x.y.z  # 替换为实际版本号

然后运行 flutter pub get 来获取依赖。

初始化

在你的主应用文件中(通常是 main.dart),你需要初始化 flutter_mqchat 插件:

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

void main() {
  // 初始化flutter_mqchat
  MqChat.instance.initialize().then((_) {
    runApp(MyApp());
  }).catchError((error) {
    print('Initialization failed: $error');
  });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter MQChat Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChatScreen(),
    );
  }
}

聊天界面

创建一个简单的聊天界面 ChatScreen

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

class ChatScreen extends StatefulWidget {
  @override
  _ChatScreenState createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final TextEditingController _messageController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Chat Screen'),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: ChatMessages(),
          ),
          Divider(),
          Container(
            decoration: BoxDecoration(color: Colors.grey[200]),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Expanded(
                  child: TextField(
                    controller: _messageController,
                    decoration: InputDecoration(border: InputBorder.none, hintText: 'Type a message...'),
                  ),
                ),
                IconButton(
                  icon: Icon(Icons.send),
                  onPressed: () async {
                    String message = _messageController.text;
                    if (message.isNotEmpty) {
                      // 发送消息
                      await MqChat.instance.sendMessage(message);
                      _messageController.clear();
                    }
                  },
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class ChatMessages extends StatefulWidget {
  @override
  _ChatMessagesState createState() => _ChatMessagesState();
}

class _ChatMessagesState extends State<ChatMessages> {
  List<String> _messages = [];

  @override
  void initState() {
    super.initState();
    // 监听新消息
    MqChat.instance.onMessageReceived.listen((message) {
      setState(() {
        _messages.insert(0, message); // 将新消息添加到顶部
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: _messages.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(_messages[index]),
        );
      },
    );
  }
}

说明

  1. 初始化:在 main 函数中,我们初始化了 flutter_mqchat 插件。
  2. 聊天界面ChatScreen 是我们的聊天界面,包含一个显示消息的 ChatMessages 小部件和一个用于输入和发送消息的文本字段。
  3. 消息监听:在 ChatMessagesinitState 方法中,我们监听了新消息事件,并将新消息添加到消息列表中。

请注意,这只是一个假设性的示例,实际的 flutter_mqchat 插件可能有不同的API和初始化方法。务必查阅该插件的官方文档或源代码以获取准确的用法。如果 flutter_mqchat 实际上不存在,你可能需要寻找其他合适的Flutter即时通讯插件,如 flutter_socket_iochat_flutter 等。

回到顶部