Flutter社交云聊天插件locality_social_cloud_chat的使用

Flutter社交云聊天插件locality_social_cloud_chat的使用

locality_social_cloud_chat 是一个用于管理一对一消息和群聊的实时聊天系统。它支持消息传递、反应、通知和邀请功能,并且与 locality_social_cloud API 集成。

功能

  • 端到端加密:使用 ECDH 椭圆曲线 M-511 和 ChaCha20 进行加密。
  • 消息反应:用户可以对消息进行预定义或自定义的反应。
  • 事件驱动架构:使用 PubSub 模型响应特定类型的消息(如文本、媒体)。
  • 群聊:邀请用户加入群聊并管理接受情况。
  • 高效的UI更新:使用 ThrottledChangeNotifier 进行优化的状态更新。
  • 消息观察者:实时跟踪消息状态(如已读、已发送和反应)。

开始使用

该项目使用了 Locality Social Cloud 库。 要使用它,你需要有一个 Social Cloud Developer Account 并获取你的应用密钥。

在项目中添加以下依赖:

flutter pub add locality_social_cloud
flutter pub add locality_social_cloud_chat
flutter pub get

配置Locality Social Cloud

Locality Social Cloud 获取你的应用ID和应用密钥,并配置它们:

LocalitySocialCloud.configure(app_id: 'YOUR_APP_ID', app_secret: 'YOUR_APP_SECRET');

然后运行 flutter pub get 安装包。

导入库

import 'package:locality_social_cloud_chat/locality_social_cloud_chat.dart';

示例用法

1. 初始化直接消息聊天

创建一个 DirectMessagesChat 实例用于一对一消息通信:

DirectMessagesChat chat = await DirectMessagesFacade.getTargetUserChat(
      loggedInUser,
      targetUser
  );

2. 发送消息

向聊天中发送一条新消息:

chat.sendMessage({
  'content': 'Hello, this is a message!',
});

你可以监听状态更新:

chat.addListener(() {
    ...
});

这是一个限流器,意味着它最多每秒调用 120 次,并且只有当有新的状态可用时才会被调用。你可以像使用 Provider 一样将其集成到你的UI中。如果你想确保某些事件在同步后才发生,可以使用 locality_social_cloud 中的 Timeline

chat.timeline.whenSynchronized(() {
    for (var chatMessage in chat.chatMessages) {
      String messageUuid = chatMessage.payload['message_uuid'];
      ....
    }
  });

3. 添加消息反应

对特定消息进行反应:

chat.reactToMessage('message_uuid_123', 'like');

4. 跟踪消息状态

你可以通过订阅 MessageObserver 来监控消息是否已送达或已读:

MessageObserver chatMessageObserver = chat.messageObserversByChatMessageUUID[messageUuid]!;
if (!messageObserver.seen) {
    print('Message not seen yet');
}
messageObserver.addListener((){
    // 当状态改变时将被调用
    if (messageObserver.seen) {
        print('Message seen');
    }
});

使用此代码块在 timeline 同步时执行:

chat.timeline.whenSynchronized(() {
    ...
});

如果你有特殊消息类型,如照片消息,会触发照片下载,你可以使用:

chat.whenMessageOfTypeReceived('photo_message', (messageObserver) {
    
});

5. 处理群聊邀请

邀请用户加入群聊或接受邀请:

chat.inviteToGroupChat('Cool Group', 'group_uuid_456', 'group_topic', BigInt.from(123456));
chat.acceptGroupChatInvitation('message_uuid_789', 'group_uuid_456');

使用邀请来创建群聊。GroupChats 类将持有从接受的邀请中生成的群聊。

GroupChats.getInstance().addListener(() {
    List<GroupChat> groupChats = GroupChats.getInstance().groupChats;
    for(GroupChat groupChat in groupChats) {
      print("We are connected to the groupchat ... "+groupChat.title);
    }
  });

事件处理

DirectMessagesChat 类监听各种聊天相关的事件(如消息添加、反应、已读、已发送等)。你可以通过实现自定义操作来处理这些事件。

进入和离开聊天

当用户进入或离开聊天时,你可以影响他们是否已经查看过消息:

chat.enterChat();  // 将所有消息标记为已读。
chat.leaveChat();  // 将聊天标记为未读。

示例代码

以下是完整的示例代码:

import 'dart:math';

import 'package:locality_social_cloud/api/discover_users.dart';
import 'package:locality_social_cloud/api/locality_auth.dart';
import 'package:locality_social_cloud/api/locality_social_cloud.dart';
import 'package:locality_social_cloud/api/locality_user.dart';
import 'package:locality_social_cloud/api/logged_in_user.dart';
import 'package:locality_social_cloud_chat/locality_social_cloud_chat.dart';

Future<LoggedInUser> getLoggedInUser() async {
  LocalitySocialCloud.configure(appId: "....", appSecret: "........");
  LoggedInUserOrError loggedInUserOrError =
      await LocalitySocialCloud.auth("userName", "password");

  if (loggedInUserOrError.isError()) {
    throw Exception(
        "Could not log in to the Locality Social Cloud. Please verify that appId and appSecret are correct.");
  }

  LoggedInUser loggedInUser = loggedInUserOrError.getUser();
  LocalitySocialCloud.connect(loggedInUser);

  return loggedInUser;
}

const bool testDiscoverUsers = false;

void main() async {
  LoggedInUser loggedInUser = await getLoggedInUser();

  if (testDiscoverUsers) {
    DiscoverUsers discoverUsers = LocalitySocialCloud.discoverUsers();

    discoverUsers.addListener(() {
      for (int i = 0; i < discoverUsers.discoveredUsers.length; i++) {
        print("Discovered user with id ${discoverUsers.discoveredUsers[i].id}");
        print("And public key ${discoverUsers.discoveredUsers[i].publicKey}");
      }
    });

    discoverUsers.startingWith("Malti");
    // 如果我们不结束这个程序,程序将在结果未知之前终止
    await Future.delayed(const Duration(milliseconds: 1000));
  }

  DirectMessagesChat chat = await DirectMessagesFacade.getTargetUserChat(
      loggedInUser,
      LocalityUser("testuser2",
          "6a090d80590af1852ff0540a2a370fa209e2662e9d7ccaeb9b704d014cc92b8e69a4cf0695284983040c22d511e46f68f9e8e0c19d3ccd19203d028cf6bdf264/6dfde80699b9e231d90a1a81cc4c5fa60f93de3f7d216a9616a7c8c9dfc686beeb23884cefb2b9f0b45cd264f0f0aa82bd518081056e73dd634e132084d5218d"));

  chat.sendMessage({
    'content': "Hello World sdf dsf !!",
  });
  chat.sendMessage({
    'content': "Hello World! dsfsd fdsf !",
  });
  chat.sendMessage({
    'content': "Hello World!!",
  });

  /// 它是一个限流器,所以它最多每秒调用120次notifyListeners,以批量方式将状态变化转移到渲染引擎。
  chat.addListener(() {
    print("LOOK! IT IS THROTTLED!");
  });

  GroupChats.getInstance().addListener(() {
    List<GroupChat> groupChats = GroupChats.getInstance().groupChats;
    for (GroupChat groupChat in groupChats) {
      print("We are connected to the groupchat ... " + groupChat.title);
    }
  });

  /// 这将在本地时间线与全局时间线同步后被调用。
  chat.timeline.whenSynchronized(() {
    for (var chatMessage in chat.chatMessages) {
      String messageUuid = chatMessage.payload['message_uuid'];
      MessageObserver chatMessageObserver =
          chat.messageObserversByChatMessageUUID[messageUuid]!;
      chatMessageObserver.addListener(() {
        print(
            "MESSAGE ${messageUuid.substring(0, 12)}... received a like. Likecounter: ${chatMessageObserver.reactions.length}");
      });
      print("CHAT MESSAGE ${chatMessage.payload}");
      if (Random().nextInt(25) > 12) {
        chat.reactToMessage(messageUuid, 'like');
      }
    }
  });

  // 我们不知道何时可以停止程序。在实践中,UI会永远运行。
  await Future.delayed(const Duration(milliseconds: 10000));
}

更多关于Flutter社交云聊天插件locality_social_cloud_chat的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter社交云聊天插件locality_social_cloud_chat的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用locality_social_cloud_chat插件的基本示例。请注意,实际使用中可能需要根据具体的API文档和需求进行调整。由于locality_social_cloud_chat是一个假想的插件名称,以下代码将基于一个假设的API结构来演示。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加locality_social_cloud_chat依赖:

dependencies:
  flutter:
    sdk: flutter
  locality_social_cloud_chat: ^1.0.0  # 假设的版本号

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

2. 导入插件

在你的Dart文件中导入插件:

import 'package:locality_social_cloud_chat/locality_social_cloud_chat.dart';

3. 初始化插件

通常,在应用的入口文件(如main.dart)中初始化插件:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 假设插件有一个初始化方法
  LocalitySocialCloudChat.initialize('your_api_key_here');
  
  runApp(MyApp());
}

4. 实现登录功能

假设插件提供了一个登录方法:

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  void _login() async {
    try {
      // 假设登录方法需要email和密码
      await LocalitySocialCloudChat.login(
        email: _emailController.text,
        password: _passwordController.text,
      );
      // 登录成功后跳转到聊天界面
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (context) => ChatScreen()),
      );
    } catch (e) {
      // 处理登录错误
      print('Login failed: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
              controller: _emailController,
              decoration: InputDecoration(labelText: 'Email'),
            ),
            TextField(
              controller: _passwordController,
              decoration: InputDecoration(labelText: 'Password'),
              obscureText: true,
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _login,
              child: Text('Login'),
            ),
          ],
        ),
      ),
    );
  }
}

5. 实现聊天功能

假设插件提供了一个获取聊天列表和发送消息的方法:

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

class _ChatScreenState extends State<ChatScreen> {
  List<Chat> _chatList = [];
  final TextEditingController _messageController = TextEditingController();

  @override
  void initState() {
    super.initState();
    // 获取聊天列表
    _fetchChatList();
  }

  void _fetchChatList() async {
    try {
      _chatList = await LocalitySocialCloudChat.getChatList();
      setState(() {});
    } catch (e) {
      print('Failed to fetch chat list: $e');
    }
  }

  void _sendMessage() async {
    try {
      // 假设发送消息需要指定的聊天ID和消息内容
      await LocalitySocialCloudChat.sendMessage(
        chatId: _chatList.first.id,  // 这里只是示例,实际应选择一个具体的聊天
        message: _messageController.text,
      );
      _messageController.clear();
      // 刷新聊天列表或获取最新消息
      _fetchChatList();
    } catch (e) {
      print('Failed to send message: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Chat')),
      body: Column(
        children: <Widget>[
          Expanded(
            child: ListView.builder(
              itemCount: _chatList.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(_chatList[index].latestMessage),
                  subtitle: Text(_chatList[index].contactName),
                );
              },
            ),
          ),
          TextField(
            controller: _messageController,
            decoration: InputDecoration(labelText: 'Message'),
            maxLines: 4,
          ),
          ElevatedButton(
            onPressed: _sendMessage,
            child: Text('Send'),
          ),
        ],
      ),
    );
  }
}

// 假设的Chat类
class Chat {
  String id;
  String contactName;
  String latestMessage;

  Chat({required this.id, required this.contactName, required this.latestMessage});
}

注意

  • 上述代码是基于假设的API结构编写的,实际使用时请参考locality_social_cloud_chat插件的官方文档。
  • 登录、获取聊天列表和发送消息的方法及其参数可能有所不同,请根据插件的实际API进行调整。
  • 错误处理和UI设计也应根据实际需求进行完善。
回到顶部