fix(client): 单实例锁改用 TCP loopback socket
文件锁在 Windows 上行为不一致,改用绑定本地端口(54317)作为互斥锁, 进程退出时 OS 自动释放,Windows/macOS 均可靠生效。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
// Keep the RAF open so the OS lock stays alive for the lifetime of the process.
|
||||
// ignore: unused_element
|
||||
RandomAccessFile? _raf;
|
||||
// Keep the server socket alive for the lifetime of the process.
|
||||
// The OS releases the port automatically when the process exits.
|
||||
ServerSocket? _server;
|
||||
|
||||
// Port unique to this app; chosen from the private range 49152–65535.
|
||||
const _kLockPort = 54317;
|
||||
|
||||
/// Returns true if this process successfully acquired the single-instance lock.
|
||||
/// Returns false if another instance is already running.
|
||||
@@ -15,11 +17,11 @@ Future<bool> acquire() async {
|
||||
if (!Platform.isWindows && !Platform.isMacOS) return true;
|
||||
|
||||
try {
|
||||
final dir = await getApplicationSupportDirectory();
|
||||
final lockFile = File('${dir.path}/jiu.lock');
|
||||
final raf = await lockFile.open(mode: FileMode.write);
|
||||
await raf.lock(FileLock.exclusive);
|
||||
_raf = raf;
|
||||
_server = await ServerSocket.bind(
|
||||
InternetAddress.loopbackIPv4,
|
||||
_kLockPort,
|
||||
shared: false,
|
||||
);
|
||||
return true;
|
||||
} catch (_) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user