socket close cleanup (#510)(#497)

This commit is contained in:
wanghongenpin
2025-08-12 14:59:11 +08:00
parent fc943dc52b
commit 7763cb3d53
2 changed files with 47 additions and 3 deletions

View File

@@ -70,29 +70,69 @@ class Server extends Network {
late ServerSocket serverSocket;
bool isRunning = false;
EventListener? listener;
StreamSubscription? serverSubscription;
final List<Channel> _connections = [];
Timer? _connectionCleanupTimer;
Server(this.configuration, {this.listener});
Future<ServerSocket> bind(int port) async {
serverSocket = await ServerSocket.bind(InternetAddress.anyIPv4, port);
serverSocket.listen((socket) {
serverSubscription = serverSocket.listen((socket) {
var channel = Channel(socket);
_connections.add(channel);
socket.done.whenComplete(() => _connections.remove(channel));
ChannelContext channelContext = ChannelContext();
channelContext.clientChannel = channel;
channelContext.listener = listener;
listen(channel, channelContext);
});
isRunning = true;
_connectionCleanupTimer = Timer.periodic(const Duration(seconds: 120), (timer) {
if (!isRunning) {
timer.cancel();
_connectionCleanupTimer = null;
return;
}
cleanupConnections();
});
return serverSocket;
}
Future<ServerSocket> stop() async {
if (!isRunning) return serverSocket;
isRunning = false;
for (var channel in _connections) {
if (channel.isClosed) continue;
try {
logger.d('Closing socket: ${channel.remoteSocketAddress.host}:${channel.remoteSocketAddress.port}');
channel.close();
} catch (e) {
logger.e('Error closing socket: $e');
}
}
_connections.clear();
//关闭监听
serverSubscription?.cancel();
serverSubscription = null;
await serverSocket.close();
_connectionCleanupTimer?.cancel();
_connectionCleanupTimer = null;
return serverSocket;
}
void cleanupConnections() {
_connections.removeWhere((channel) {
if (channel.isClosed) {
logger.i('Cleaning up closed channel: ${channel.remoteSocketAddress.host}:${channel.remoteSocketAddress.port}');
return true;
}
return false;
});
}
@override
Future<void> onEvent(Uint8List data, ChannelContext channelContext, Channel channel) async {
//手机扫码转发远程地址

View File

@@ -17,8 +17,9 @@ import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:proxypin/l10n/app_localizations.dart';
import 'package:flutter/services.dart';
import 'package:flutter_toastr/flutter_toastr.dart';
import 'package:proxypin/l10n/app_localizations.dart';
import 'package:proxypin/native/vpn.dart';
import 'package:proxypin/network/bin/server.dart';
import 'package:proxypin/network/util/logger.dart';
@@ -93,9 +94,13 @@ class _SocketLaunchState extends State<SocketLaunch> with WindowListener, Widget
}
Future<void> appExit() async {
logger.d("appExit");
await widget.proxyServer.stop();
started = false;
windowManager.setPreventClose(false);
await windowManager.destroy();
await SystemNavigator.pop();
exit(0);
}
@@ -108,7 +113,6 @@ class _SocketLaunchState extends State<SocketLaunch> with WindowListener, Widget
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
if (widget.proxyServer.isRunning) {
widget.proxyServer.retryBind();
}