implement refreshing chat screen(This foundation really kills me)

main
htylight 2023-09-20 20:21:27 +08:00
parent dbfb24defc
commit e7d9f02137
2 changed files with 56 additions and 17 deletions

View File

@ -30,7 +30,7 @@ class WebSocketManager extends ChangeNotifier {
Timer? heartBeatTimer; Timer? heartBeatTimer;
Timer? serverTimer; Timer? serverTimer;
Timer? reconnectTimer; Timer? reconnectTimer;
int reconnectCount = 10; int reconnectCount = 5;
int reconnectTimes = 0; int reconnectTimes = 0;
Duration heartBeatTimeout = const Duration(seconds: 4); Duration heartBeatTimeout = const Duration(seconds: 4);
Duration reconnectTimeout = const Duration(seconds: 3); Duration reconnectTimeout = const Duration(seconds: 3);
@ -38,6 +38,10 @@ class WebSocketManager extends ChangeNotifier {
void connect(String userId, bool isReconnect) { void connect(String userId, bool isReconnect) {
id = userId; id = userId;
wsUrl = Uri.parse('ws://10.0.2.2:8000/ws/$id?is_reconnect=$isReconnect'); wsUrl = Uri.parse('ws://10.0.2.2:8000/ws/$id?is_reconnect=$isReconnect');
if (isReconnect) {
socketStatus = SocketStatus.reconnecting;
notifyListeners();
}
// This doesn't blcok the programe whethe it connect the server or not // This doesn't blcok the programe whethe it connect the server or not
// So heartBeat will be executre straightly // So heartBeat will be executre straightly
channel = WebSocketChannel.connect(wsUrl); channel = WebSocketChannel.connect(wsUrl);
@ -97,7 +101,7 @@ class WebSocketManager extends ChangeNotifier {
// for example server is restarting // for example server is restarting
void onDone() { void onDone() {
print('websocket disconnected <$channel>'); print('websocket disconnected <$channel>');
print('22222222222222222222');
if (socketStatus == SocketStatus.closed) { if (socketStatus == SocketStatus.closed) {
// Client close the connection // Client close the connection
return; return;
@ -112,6 +116,11 @@ class WebSocketManager extends ChangeNotifier {
} }
if (reconnectTimes >= reconnectCount) { if (reconnectTimes >= reconnectCount) {
socketStatus = SocketStatus.error; socketStatus = SocketStatus.error;
reconnectTimes = 0;
} else {
socketStatus = SocketStatus.reconnecting;
print('3333333333333333333');
notifyListeners();
} }
} }
@ -121,12 +130,12 @@ class WebSocketManager extends ChangeNotifier {
// print(st); // print(st);
if (reconnectTimes >= reconnectCount) { if (reconnectTimes >= reconnectCount) {
socketStatus = SocketStatus.error; socketStatus = SocketStatus.error;
notifyListeners();
channel.sink.close();
if (heartBeatTimer != null) { if (heartBeatTimer != null) {
heartBeatTimer!.cancel(); heartBeatTimer!.cancel();
heartBeatTimer = null; heartBeatTimer = null;
} }
channel.sink.close();
notifyListeners();
} else { } else {
print('${reconnectTimes}th reconnection'); print('${reconnectTimes}th reconnection');
reconnect(); reconnect();

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
@ -150,11 +152,30 @@ class _ChatScreenState extends State<ChatScreen> with GetItStateMixin {
Expanded( Expanded(
child: RefreshIndicator( child: RefreshIndicator(
onRefresh: () async { onRefresh: () async {
String userId = getIt.get<UserAccount>().id; if (socketStatus == SocketStatus.reconnecting) {
if (socketStatus == SocketStatus.error) { return;
getIt.get<WebSocketManager>().connect(userId, false); }
String userId = getIt.get<UserAccount>().id;
if (socketStatus != SocketStatus.connected) {
getIt.get<WebSocketManager>().connect(userId, true);
await Future.doWhile(() async {
SocketStatus socketStatus =
get<WebSocketManager>().socketStatus;
await Future.delayed(
const Duration(milliseconds: 500),
);
return socketStatus == SocketStatus.reconnecting;
});
SocketStatus socketStatus =
get<WebSocketManager>().socketStatus;
if (socketStatus == SocketStatus.connected) {
await _getUnreceivedMsg(userId);
}
} }
await _getUnreceivedMsg(userId);
}, },
child: ValueListenableBuilder( child: ValueListenableBuilder(
valueListenable: valueListenable:
@ -171,15 +192,24 @@ class _ChatScreenState extends State<ChatScreen> with GetItStateMixin {
); );
if (openedChat.isEmpty) { if (openedChat.isEmpty) {
return const Center( return LayoutBuilder(builder: (context, constrains) {
child: Text( return ListView(
'没有最新消息', itemExtent: constrains.maxHeight / 3,
style: TextStyle( children: const [
fontSize: 18, SizedBox(),
letterSpacing: 5.0, Center(
), child: Text(
), '没有最新消息',
); style: TextStyle(
fontSize: 18,
letterSpacing: 4.0,
),
),
),
SizedBox(),
],
);
});
} else { } else {
return ListView.builder( return ListView.builder(
physics: const BouncingScrollPhysics( physics: const BouncingScrollPhysics(