Flutter会话管理插件sessionful的使用

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

Flutter会话管理插件sessionful的使用

Sessionful

Pub Package GitHub Issues GitHub Forks GitHub Stars GitHub License

什么是它?

这是一个库,允许你通过单一字节流创建多个通信通道。这使得可以创建独立于彼此的小型上下文会话。会话对象与负载无关。编码和解码负载超出了此包的范围。

支持的功能

API非常简单且仅限于我所需的功能。将来可能会(或可能不会)扩展,如果您有任何建议,欢迎在GitHub上提交PR或FR。

  • 使用自动生成的会话ID创建会话。
  • 检测传入的新会话。
  • 能够按需终止会话(发送方和接收方都可以)。
  • 推拉支持(发送并请求响应)。
  • 推+拉支持(发送时不等待响应,随时读取响应)。
  • 检查会话中是否有任何等待的数据。

如何使用

请参考示例以了解其基本工作原理。单元测试提供了更多使用示例。

示例代码

import 'dart:convert';
import 'dart:typed_data';

import 'package:sessionful/sessionful.dart';

class Client {
  final String name;
  late final SessionsDispatcher dispatcher;
  final List<Session> sessions = [];

  Client(this.name, AttachableSink incomingData, AttachableSink outgoingData) {
    dispatcher = SessionsDispatcher(
        outputSink: outgoingData,
        onNewSessionDiscovered: (session) {
          print("[$name] new session with id ${session.sessionId}");
          sessions.add(session);
        },
        onSessionTerminated: (session) {
          print("[$name] Terminate session with id ${session.sessionId}");
          sessions.removeWhere((e) => e.sessionId == session.sessionId);
        });
    incomingData.destination = dispatcher;
  }

  /// Try to send in specified session, if session not exist create new one (id will be generated)
  int sendInSession(int sessionId, String data) {
    Session? session = _getSessionById(sessionId);
    if (session == null) {
      session = dispatcher.createSession();
      sessions.add(session);
    }
    final payload = utf8.encoder.convert(data);
    session.push([payload]);
    return session.sessionId;
  }

  String? readFromSession(int sessionId) {
    String? result;
    Session? session = _getSessionById(sessionId);
    final payload = session?.maybePull();
    if (payload != null) {
      result = utf8.decoder.convert(payload);
    }
    return result;
  }

  /// Get session by its id
  Session? _getSessionById(int sessionId) {
    Session? session;
    for (var s in sessions) {
      if (s.sessionId == sessionId) {
        session = s;
        break;
      }
    }
    return session;
  }
}

/// A sink that can be attached to another sink.
class AttachableSink implements Sink<Uint8List> {
  Sink<Uint8List>? destination;

  [@override](/user/override)
  void add(Uint8List data) => destination?.add(data);

  [@override](/user/override)
  void close() => destination?.close();
}

/// A class representing a transport mechanism.
class Transport {
  final AttachableSink fromClientAToB = AttachableSink();
  final AttachableSink fromClientBToA = AttachableSink();
}

void main() {
  final transport = Transport();
  final clientA = Client("A", transport.fromClientAToB, transport.fromClientBToA);
  final clientB = Client("B", transport.fromClientBToA, transport.fromClientAToB);

  // 发送数据到两个不同的会话
  final sessionId1 = clientA.sendInSession(-1, "This text is send in session 1");
  final sessionId2 = clientA.sendInSession(-1, "This text is send in session 2");

  // 客户端B读取来自客户端A的数据
  for (Session s in clientB.sessions) {
    final incomingText = clientB.readFromSession(s.sessionId);
    print("ClientB [Session ${s.sessionId}] got text: $incomingText");
  }

  // 客户端B向客户端A发送响应
  clientB.sendInSession(clientB.sessions.first.sessionId, "This is response");

  // 客户端A读取响应
  final incomingText = clientA.readFromSession(sessionId1);
  print("ClientA [Session $sessionId1] got response: $incomingText");
}

更多关于Flutter会话管理插件sessionful的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter会话管理插件sessionful的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用sessionful插件进行会话管理的示例代码。sessionful是一个用于Flutter的状态管理库,它允许你轻松地在应用程序的不同部分之间共享和持久化状态。

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

dependencies:
  flutter:
    sdk: flutter
  sessionful: ^最新版本号  # 请替换为实际的最新版本号

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

接下来,让我们看看如何使用sessionful进行会话管理。以下是一个简单的示例,展示了如何设置sessionful、存储和检索数据。

1. 初始化Sessionful

在你的应用程序的入口文件(通常是main.dart)中,初始化Sessionful

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

void main() {
  // 初始化Sessionful
  final sessionful = Sessionful.instance;

  // 配置持久化选项(可选)
  sessionful.configure(
    storageOptions: StorageOptions(
      localStorage: true,  // 是否使用本地存储
      sharedPreferences: true,  // 是否使用SharedPreferences
    ),
  );

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

2. 存储数据

在一个屏幕(例如HomeScreen)中,存储一些数据到会话中:

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

class HomeScreen extends StatelessWidget {
  final sessionful = Sessionful.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 存储数据到会话
            sessionful.set('user', {'name': 'John Doe', 'age': 30});

            // 导航到另一个屏幕
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => DetailsScreen()),
            );
          },
          child: Text('Store Data and Navigate'),
        ),
      ),
    );
  }
}

3. 检索数据

在另一个屏幕(例如DetailsScreen)中,检索存储的数据:

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

class DetailsScreen extends StatelessWidget {
  final sessionful = Sessionful.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details Screen'),
      ),
      body: FutureBuilder<Map<String, dynamic>>(
        future: sessionful.get<Map<String, dynamic>>('user'),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            if (snapshot.hasError) {
              return Center(child: Text('Error: ${snapshot.error}'));
            } else if (snapshot.hasData) {
              final user = snapshot.data!;
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('Name: ${user['name']}'),
                    Text('Age: ${user['age']}'),
                  ],
                ),
              );
            } else {
              return Center(child: Text('No data found'));
            }
          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

在这个示例中,我们在HomeScreen中存储了一个用户对象,并在DetailsScreen中检索并显示它。sessionful.set方法用于存储数据,而sessionful.get方法用于检索数据。

这个示例展示了sessionful的基本用法,但sessionful还提供了许多其他功能,如监听会话变化、自动持久化等,你可以根据需求进一步探索和使用这些功能。

回到顶部