首页 > 解决方案 > Flutter 在 App Idle 或 Inactive 时检索 Socket 消息

问题描述

我正在编写一个使用 Pusher 的聊天应用程序。当应用程序在屏幕上时消息发送成功,但是当应用程序在后台运行时,套接字会在一段时间后自行关闭并停止接收发送者的消息。

我能做些什么来克服这个问题?它必须适用于 Android 或 iOS。如果是与推送器相关的错误,我也可以将我的代码转换为 socket.io。

我的代码如下。 pusher.dart

class AppPusher {
  static final _appPusher = AppPusher._internal();

  AppPusher._internal();

  factory AppPusher() {
    return _appPusher;
  }

  final String _messaging = 'messaging';
  final String _notifications = 'notifications';

  PusherClient? _pusher;

  Channel? _channel;
  String? _channelName;

  final _pusherData = StreamController<SocketResult>.broadcast();
  Stream<SocketResult> get stream => _pusherData.stream;

  void connect({required Me me}) {
    if (_pusher == null) {
      final token = _getToken();

      _pusher = PusherClient(
        AppSettings.pusher.key,
        PusherOptions(
          cluster: AppSettings.pusher.cluster,
          encrypted: true,
          auth: PusherAuth(
            AppSettings.pusher.url,
            headers: {'Authorization': 'Bearer $token'},
          ),
        ),
        autoConnect: true,
        enableLogging: AppSettings.pusher.enableLogging,
      );

      _channelName = 'private-user-${me.id}';

      _channel = _pusher!.subscribe(_channelName!);

      _channel!.bind(_messaging, (event) {
        if (event != null) {
          _pusherData.sink.add(SocketResult<SocketMessage>(
            type: ChannelType.message,
            me: me,
            data: SocketMessage.fromJson(jsonDecode(event.data!)),
          ));
        }
      });

      _channel!.bind(_notifications, (event) {
        if (event != null) {
          _pusherData.sink.add(SocketResult<SocketNotification>(
            type: ChannelType.notification,
            me: me,
            data: SocketNotification.fromJson(jsonDecode(event.data!)),
          ));
        }
      });
    }
  }

  void disconnect() async {
    _pusherData.close();

    if (_pusher != null) {
      if (_channel != null) {
        await _channel!.unbind(_messaging);
        await _channel!.unbind(_notifications);
      }
      if (_channelName != null) {
        await _pusher!.unsubscribe(_channelName!);
      }
      await _pusher!.disconnect();
    }
  }

  String _getToken() {
    return locator<SharedPreferencesManager>()
            .getString(SharedPreferencesManager.accessToken) ??
        '';
  }
}

应用程序.dart

void initPusher() {
  _pusher.connect(me: context.read<MeProvider>().me!);

  _streamSubscription = _pusher.stream.listen((event) {
    switch (event.type) {
      case ChannelType.message:
        context
            .read<ChatProvider>()
            .socketMessage(message: event.data, me: event.me);
        break;
      case ChannelType.notification:
        print('EVENT FROM NOTIFICATION: ${event.data}');
        break;
    }
  });
}

@override
void initState() {
  super.initState();

  WidgetsBinding.instance?.addPostFrameCallback((_) {
    initPusher();
  });
}

@override
void dispose() {
  _streamSubscription.cancel();
  _pusher.disconnect();

  super.dispose();
}

标签: androidiosfluttersocket.iopusher

解决方案


推荐阅读