@@ -4,11 +4,13 @@ import 'dart:io';
44
55import 'package:connectivity_plus/connectivity_plus.dart' ;
66import 'package:flutter/material.dart' ;
7+ import 'package:flutter_speedtest/flutter_speedtest.dart' ;
78import 'package:http/http.dart' as http;
89import 'package:http/io_client.dart' ;
910import 'package:ir_net/data/leak_item.dart' ;
1011import 'package:ir_net/data/shared_preferences.dart' ;
1112import 'package:ir_net/utils/cmd.dart' ;
13+ import 'package:ir_net/utils/http.dart' ;
1214import 'package:ir_net/utils/system_tray.dart' ;
1315import 'package:latlng/latlng.dart' ;
1416import 'package:live_event/live_event.dart' ;
@@ -21,6 +23,10 @@ class AppBloc with AppSystemTray {
2123 final _clearLeakInput = LiveEvent ();
2224 final _leakChecklist = BehaviorSubject <List <LeakItem >>();
2325 final _localNetwork = BehaviorSubject <LocalNetworksResult >();
26+ final _ping = BehaviorSubject <double ?>();
27+ final _downloadSpeed = BehaviorSubject <double ?>();
28+ final _uploadSpeed = BehaviorSubject <double ?>();
29+ final _speedTestStatus = BehaviorSubject <String >();
2430
2531 bool _isPingingGoogle = false ;
2632 bool _foundALeakedSite = false ;
@@ -32,6 +38,17 @@ class AppBloc with AppSystemTray {
3238 Stream get clearLeakInput => _clearLeakInput.stream;
3339 Stream <List <LeakItem >> get leakChecklist => _leakChecklist.stream;
3440 Stream <LocalNetworksResult > get localNetwork => _localNetwork.stream;
41+ Stream <double ?> get ping => _ping.stream;
42+ Stream <double ?> get downloadSpeed => _downloadSpeed.stream;
43+ Stream <double ?> get uploadSpeed => _uploadSpeed.stream;
44+ Stream <String > get speedTestStatus => _speedTestStatus.stream;
45+
46+ final speedtest = FlutterSpeedtest (
47+ baseUrl: 'http://speedtest.jaosing.com:8080' ,
48+ pathDownload: '/download' ,
49+ pathUpload: '/upload' ,
50+ pathResponseTime: '/ping' ,
51+ );
3552
3653 void onLeakInputChanged (String value) {
3754 _leakInput = value;
@@ -110,7 +127,7 @@ class AppBloc with AppSystemTray {
110127 item.status = LeakStatus .failed;
111128 }
112129 debugPrint ('leak detection for $url => ${response .bodyBytes .length ~/ 1024 } Kilobytes' );
113- } on Exception catch (ex) {
130+ } on Exception catch (ex) {
114131 item.status = LeakStatus .failed;
115132 _checkNetworkRefuseException (ex);
116133 }
@@ -131,12 +148,17 @@ class AppBloc with AppSystemTray {
131148 await _checkProxySettings ();
132149 _checkIpLocation ();
133150 _verifyLeakedSites ();
151+ _checkPing ();
134152 } else {
135153 setSystemTrayStatusToOffline ();
136154 }
137155 });
138156 }
139157
158+ void _checkPing () async {
159+ _ping.value = await HttpUtils .measureHttpPing ();
160+ }
161+
140162 void _runIpCheckInfinitely () async {
141163 while (true ) {
142164 await _checkProxySettings ();
@@ -154,14 +176,15 @@ class AppBloc with AppSystemTray {
154176 _isPingingGoogle = false ;
155177 _checkNetworkConnectivity ();
156178 return ;
157- } on SocketException catch (ex) {
179+ } on SocketException catch (ex) {
158180 _checkNetworkRefuseException (ex);
159181 }
160182 _isPingingGoogle = false ;
161183 }
162184
163185 void _checkNetworkRefuseException (Exception ex) {
164- if (ex is SocketException && ex.message.startsWith ('The remote computer refused the network connection.' )) {
186+ if (ex is SocketException &&
187+ ex.message.startsWith ('The remote computer refused the network connection.' )) {
165188 _proxyServer = null ;
166189 }
167190 }
@@ -222,6 +245,31 @@ class AppBloc with AppSystemTray {
222245 }
223246 }
224247
248+ void onConnectionTestClick () async {
249+ _downloadSpeed.value = 0 ;
250+ _uploadSpeed.value = 0 ;
251+ _speedTestStatus.value = 'Running' ;
252+ speedtest.getDataspeedtest (
253+ downloadOnProgress: ((percent, transferRate) {
254+ _downloadSpeed.value = transferRate;
255+ }),
256+ uploadOnProgress: ((percent, transferRate) {
257+ _uploadSpeed.value = transferRate;
258+ }),
259+ progressResponse: ((responseTime, jitter) {
260+ // nothing to do
261+ }),
262+ onError: ((errorMessage) {
263+ _downloadSpeed.value = 0 ;
264+ _uploadSpeed.value = 0 ;
265+ _speedTestStatus.value = 'Error' ;
266+ }),
267+ onDone: () {
268+ _speedTestStatus.value = 'Done' ;
269+ },
270+ );
271+ }
272+
225273 void onExitClick () {
226274 destroySystemTray ();
227275 exit (0 );
@@ -238,6 +286,7 @@ class AppBloc with AppSystemTray {
238286
239287 void _handleRefresh () async {
240288 await _checkProxySettings ();
289+ _checkPing ();
241290 _pingGoogle ();
242291 _checkIpLocation ();
243292 _verifyLeakedSites ();
0 commit comments