我在Flutter应用上使用SignalR推送通知,运行正常。我从后端收到消息,并使用flutter_local_notifications显示通知。问题是SignalR服务会在一段时间后关闭。我如何让我的应用在后台运行?甚至在重启时启动?
下面是我的代码:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:isolate_test/Model/UserMessageModel.dart';
import 'package:signalr_core/signalr_core.dart';
import 'EndPointService.dart';
import 'NotificationService.dart';
class SignalRProvider {
static String appName = "NOTIFICATION";
static String? userName = "";
static String deviceName = "android_app";
static List<UserMessageModel> messages = <UserMessageModel>[];
HubConnection connection = HubConnectionBuilder()
.withUrl(
'my_url',
HttpConnectionOptions(
logging: (level, message) => print(message),
))
.withAutomaticReconnect()
.withHubProtocol(JsonHubProtocol())
.build();
Function(bool update)? onMessagesUpdateCallback;
SignalRProvider({
this.onMessagesUpdateCallback,
});
setUsername(String username) {
userName = username;
}
Future initSignalR(BuildContext context) async {
WidgetsFlutterBinding.ensureInitialized();
await NotificationService().init();
connection.on('SignalRUserReceiveMessage', (message) async {
var data = message!.first;
if (data != null) {
UserMessageModel msg = UserMessageModel.fromJson(data);
messages.add(msg);
msg.showNotification();
}
if (onMessagesUpdateCallback != null) {
onMessagesUpdateCallback!(true);
}
});
connection.on('SignalRMonitoringMessage', (message) async {
var data = message!.first;
if (data != null) {
UserMessageModel msg = UserMessageModel.fromJson(data);
messages.add(msg);
msg.showNotification();
}
if (onMessagesUpdateCallback != null) {
onMessagesUpdateCallback!(true);
}
});
connection.on("SignalRReceiveConnectedMessage", (message) async {
await connection.send(methodName: 'SignalRInit', args: [
userName,
appName,
connection.connectionId,
]);
});
connection.on("SignalRReceiveDisconnectedMessage", (message) async {
if (connection.state == HubConnectionState.disconnected) {
connection.start();
}
});
await connection.start();
}
List<UserMessageModel> getMessages() {
return messages;
}
Future deleteMessage(UserMessageModel _msg) async {
if (_msg == null) return;
var response =
await EndPointService().SetupApi("Message", "", []).httpDelete(
HeaderEnum.BasicHeaderEnum,
ResponseEnum.ResponseModelEnum,
jsonEncode(_msg),
);
}
addOrUpdateMessage(UserMessageModel _msg) {
if (_msg == null) return;
if (messages != null) {
var found =
messages.firstWhere((e) => e.user == _msg.user && e.id == _msg.id);
var index =
messages.indexWhere((e) => e.user == _msg.user && e.id == _msg.id);
if (found != null) {
messages[index] = _msg;
} else {
messages.add(_msg);
}
if (onMessagesUpdateCallback != null) {
onMessagesUpdateCallback!(true);
}
}
}
setMessagesUpdateCallback(Function(bool update) func) {
onMessagesUpdateCallback = func;
}
}
2条答案
按热度按时间9avjhtql1#
信号R问题
SignalR for Flutter使用Web套接字和SSE接收来自SignalR服务的消息。如果应用程序因用户重启手机或操作系统关闭应用程序以保存电池电量而终止,则这些推送通知不会被应用程序接收。
为了克服这一点,应用程序开发人员(和SignalR)必须在Android上使用FCM,在iOS上使用APNs(或者FCM,它也会在iOS上使用苹果推送通知)。所有其他的方法都会受到更多的限制,因为操作系统不允许用户让后台进程一直运行。这实际上在几年前就被允许了,但操作系统已经做出了这些更改以节省用户电池-它们强制所有应用程序都通过相同的推送通知介质-Android上的FCM,iOS上的APNs。
SignalR for Flutter既不使用FCM,也不使用APNs。在目前的状态下,SignalR并不适合Android或iOS --看看How to use signalr in Android上那些与你有类似问题的人的评论。
替代解决方案
最简单的入门方法是使用Firebase Cloud Messaging。
注意事项:在Android上,有一个更复杂的替代方案,称为unifiedpush,但其限制包括向用户显示通知在任何时候以处理后台通知。
**我的分析:**这都是基于我通过阅读
pubspec.yaml
、original repo和SignalR documentation上的GitHub问题以及一些实现Flutter推送通知的经验进行的快速调查。**披露:**我两天前刚刚发布了一个推送通知库,名为
push
,它非常适合这些类型的推送通知包,可以在Android上使用FCM,在iOS上使用APNs。但是,作为一个应用开发人员,在大多数情况下,你应该使用firebase_messaging
,而不是push
。c3frrgcw2#
我使用SignalR,但在原生平台(IOS和Android)上,我制作了股票应用程序并获得实时价格。当应用程序进入后台时,我将在5秒后断开与SignalR服务器的连接,当应用程序再次进入前台时,我检查应用程序的当前状态是否未连接到SignalR服务器,我将再次连接。我认为如果您的应用程序仍在后台状态连接并接收来自SignalR服务器的数据,这是不好的。