Flutter即时通讯插件xmpp_stone的使用

Flutter即时通讯插件xmpp_stone的使用

XmppStone

轻量级的XMPP客户端库,完全用Dart编写。 我的目标是为基于Flutter的未来XMPP客户端编写一个简单易用的库。

支持的文档:

  • RFC6120:可扩展的消息和存在协议(XMPP):核心
  • RFC6121:可扩展的消息和存在协议(XMPP):即时消息和存在
  • XEP-0198:流管理
  • XEP-0085:聊天状态通知
  • XEP-0318:客户端发起的存在探测最佳实践
  • XEP-0280:消息碳副本

部分支持:

  • XEP-0030:服务发现
  • XEP-0313:消息存档管理

积极开发中:

  • XEP-0059:结果集管理
  • XEP-0004:数据表单

最新动态

  • 2020-10-30:添加了对XEP-0280:消息碳副本的支持
  • 2020-10-30:添加了对XEP-0313:消息存档管理的初步支持
  • 2020-10-30:添加了日志机制
  • 2020-07-23:添加了对XEP-0318:客户端发起的存在探测最佳实践的支持
  • 2020-05-02:添加了对XEP-0198:流管理的初步支持
  • 2020-05-02:添加了对XEP-0085:聊天状态通知的初步支持
  • 2019-04-02:添加了对XEP-0054:vcard-temp的支持
  • 2019-04-01:添加了对SHA-1和SHA-256认证算法的支持

使用方法

import 'package:xmpp_stone/xmpp_stone.dart' as xmpp;

main() {
  xmpp.Connection connection = new xmpp.Connection("user[@domain](/user/domain)", "password", 5222);
  connection.open();
}

特性

1. 日志记录
日志级别

可以通过以下命令设置库的日志级别:

Log.logLevel = LogLevel.VERBOSE;
XMPP流量日志

可以通过以下命令启用或禁用XMPP流量日志:

Log.logXmpp = false;
2. 消息存档管理

该功能正在开发中,API可能会更改。

初始实现的消息存档管理。

RST尚未实现。

使用方法:

  • 获取模块
connection.getMamModule();
  • 查询所有消息
mamManager.queryAll();
  • 基于日期查询消息(所有参数都是可选的)
mamManager.queryByTime(start: startTime, end: endTime, jid: buddyJid);
  • 基于消息ID查询消息(所有参数都是可选的) 这个方法需要urn:xmpp:mam:2#extended由服务器支持,不久后将提供检查功能支持的方法。
mamManager.queryById(beforeId: beforeId, afterId: afterId, jid: buddyJid);
  • 检查服务器的功能
mamManager.isQueryByDateSupported
mamManager.isQueryByIdSupported
mamManager.isQueryByJidSupported

完整示例代码

import 'dart:async';
import 'dart:convert';
import 'package:xmpp_stone/src/logger/Log.dart';
import 'package:xmpp_stone/xmpp_stone.dart' as xmpp;
import 'dart:io';
import 'package:console/console.dart';
import 'package:image/image.dart' as image;

final String TAG = 'example';

void main(List<String> arguments) {
  Log.logLevel = LogLevel.DEBUG;
  Log.logXmpp = false;
  Log.d(TAG, 'Type user[@domain](/user/domain):');
  var userAtDomain = 'nemanja@127.0.0.1';
  Log.d(TAG, 'Type password');
  var password = '1';
  var jid = xmpp.Jid.fromFullJid(userAtDomain);
  var account = xmpp.XmppAccountSettings(userAtDomain, jid.local, jid.domain, password, 5222, resource: 'xmppstone');
  var connection = xmpp.Connection(account);
  connection.connect();
  xmpp.MessagesListener messagesListener = ExampleMessagesListener();
  ExampleConnectionStateChangedListener(connection, messagesListener);
  var presenceManager = xmpp.PresenceManager.getInstance(connection);
  presenceManager.subscriptionStream.listen((streamEvent) {
    if (streamEvent.type == xmpp.SubscriptionEventType.REQUEST) {
      Log.d(TAG, 'Accepting presence request');
      presenceManager.acceptSubscription(streamEvent.jid);
    }
  });
  var receiver = 'nemanja2[@test](/user/test)';
  var receiverJid = xmpp.Jid.fromFullJid(receiver);
  var messageHandler = xmpp.MessageHandler.getInstance(connection);
  getConsoleStream().asBroadcastStream().listen((String str) {
    messageHandler.sendMessage(receiverJid, str);
  });
}

class ExampleConnectionStateChangedListener implements xmpp.ConnectionStateChangedListener {
  xmpp.Connection _connection;
  xmpp.MessagesListener _messagesListener;

  StreamSubscription<String> subscription;

  ExampleConnectionStateChangedListener(xmpp.Connection connection, xmpp.MessagesListener messagesListener) {
    _connection = connection;
    _messagesListener = messagesListener;
    _connection.connectionStateStream.listen(onConnectionStateChanged);
  }

  [@override](/user/override)
  void onConnectionStateChanged(xmpp.XmppConnectionState state) {
    if (state == xmpp.XmppConnectionState.Ready) {
      Log.d(TAG, 'Connected');
      var vCardManager = xmpp.VCardManager(_connection);
      vCardManager.getSelfVCard().then((vCard) {
        if (vCard != null) {
          Log.d(TAG, 'Your info' + vCard.buildXmlString());
        }
      });
      var messageHandler = xmpp.MessageHandler.getInstance(_connection);
      var rosterManager = xmpp.RosterManager.getInstance(_connection);
      messageHandler.messagesStream.listen(_messagesListener.onNewMessage);
      sleep(const Duration(seconds: 1));
      var receiver = 'nemanja2[@test](/user/test)';
      var receiverJid = xmpp.Jid.fromFullJid(receiver);
      rosterManager.addRosterItem(xmpp.Buddy(receiverJid)).then((result) {
        if (result.description != null) {
          Log.d(TAG, 'add roster' + result.description);
        }
      });
      sleep(const Duration(seconds: 1));
      vCardManager.getVCardFor(receiverJid).then((vCard) {
        if (vCard != null) {
          Log.d(TAG, 'Receiver info' + vCard.buildXmlString());
          if (vCard != null && vCard.image != null) {
            var file = File('test456789.jpg')..writeAsBytesSync(image.encodeJpg(vCard.image));
            Log.d(TAG, 'IMAGE SAVED TO: ${file.path}');
          }
        }
      });
      var presenceManager = xmpp.PresenceManager.getInstance(_connection);
      presenceManager.presenceStream.listen(onPresence);
    }
  }

  void onPresence(xmpp.PresenceData event) {
    Log.d(TAG, 'presence Event from ' + event.jid.fullJid + ' PRESENCE: ' + event.showElement.toString());
  }
}

Stream<String> getConsoleStream() {
  return Console.adapter.byteStream().map((bytes) {
    var str = ascii.decode(bytes);
    str = str.substring(0, str.length - 1);
    return str;
  });
}

class ExampleMessagesListener implements xmpp.MessagesListener {
  [@override](/user/override)
  void onNewMessage(xmpp.MessageStanza message) {
    if (message.body != null) {
      Log.d(TAG, format(
          'New Message from {color.blue}${message.fromJid.userAtDomain}{color.end} message: {color.red}${message.body}{color.end}'));
    }
  }
}

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

1 回复

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


xmpp_stone 是一个用于 Flutter 的 XMPP(Extensible Messaging and Presence Protocol)插件,它允许你在 Flutter 应用中实现即时通讯功能。XMPP 是一种开放的、基于 XML 的协议,广泛用于即时通讯、在线状态、多用户聊天等场景。

以下是如何在 Flutter 项目中使用 xmpp_stone 插件的基本步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 xmpp_stone 依赖:

dependencies:
  flutter:
    sdk: flutter
  xmpp_stone: ^0.6.0  # 请检查最新版本

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

2. 初始化 XMPP 连接

在你的 Dart 代码中,你可以初始化一个 XMPP 连接并进行身份验证。

import 'package:xmpp_stone/xmpp_stone.dart';

void connectToXmpp() {
  var connection = XmppConnection(
    'example.com',  // XMPP 服务器地址
    'username',     // 用户名
    'password',     // 密码
  );

  connection.connect().then((_) {
    print('Connected to XMPP server');
  }).catchError((error) {
    print('Failed to connect: $error');
  });
}

3. 处理消息

你可以监听消息事件来处理收到的消息。

void handleMessages(XmppConnection connection) {
  connection.messagesStream.listen((message) {
    print('Received message: ${message.body}');
  });
}

4. 发送消息

你可以使用 connection 对象发送消息。

void sendMessage(XmppConnection connection, String to, String body) {
  var message = Message();
  message.toJid = Jid(to);
  message.body = body;
  connection.sendMessage(message);
}

5. 处理连接状态

你可以监听连接状态的变化。

void handleConnectionState(XmppConnection connection) {
  connection.connectionStateStream.listen((state) {
    print('Connection state changed to: $state');
  });
}

6. 断开连接

当你不再需要连接时,可以断开连接。

void disconnect(XmppConnection connection) {
  connection.disconnect();
}

7. 完整示例

以下是一个完整的示例,展示了如何使用 xmpp_stone 进行连接、发送和接收消息。

import 'package:xmpp_stone/xmpp_stone.dart';

void main() {
  var connection = XmppConnection(
    'example.com',  // XMPP 服务器地址
    'username',     // 用户名
    'password',     // 密码
  );

  connection.connect().then((_) {
    print('Connected to XMPP server');

    // 处理消息
    connection.messagesStream.listen((message) {
      print('Received message: ${message.body}');
    });

    // 发送消息
    sendMessage(connection, 'user@example.com', 'Hello, World!');

    // 处理连接状态
    connection.connectionStateStream.listen((state) {
      print('Connection state changed to: $state');
    });

  }).catchError((error) {
    print('Failed to connect: $error');
  });
}

void sendMessage(XmppConnection connection, String to, String body) {
  var message = Message();
  message.toJid = Jid(to);
  message.body = body;
  connection.sendMessage(message);
}
回到顶部