terminal_connection_manager.dart 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import 'package:flutter/foundation.dart';
  2. import 'package:get/get.dart';
  3. import '../../models/model.dart';
  4. /// Manages terminal connections to ensure one FFI instance per peer
  5. class TerminalConnectionManager {
  6. static final Map<String, FFI> _connections = {};
  7. static final Map<String, int> _connectionRefCount = {};
  8. // Track service IDs per peer
  9. static final Map<String, String> _serviceIds = {};
  10. /// Get or create an FFI instance for a peer
  11. static FFI getConnection({
  12. required String peerId,
  13. required String? password,
  14. required bool? isSharedPassword,
  15. required bool? forceRelay,
  16. required String? connToken,
  17. }) {
  18. final existingFfi = _connections[peerId];
  19. if (existingFfi != null && !existingFfi.closed) {
  20. // Increment reference count
  21. _connectionRefCount[peerId] = (_connectionRefCount[peerId] ?? 0) + 1;
  22. debugPrint('[TerminalConnectionManager] Reusing existing connection for peer $peerId. Reference count: ${_connectionRefCount[peerId]}');
  23. return existingFfi;
  24. }
  25. // Create new FFI instance for first terminal
  26. debugPrint('[TerminalConnectionManager] Creating new terminal connection for peer $peerId');
  27. final ffi = FFI(null);
  28. ffi.start(
  29. peerId,
  30. password: password,
  31. isSharedPassword: isSharedPassword,
  32. forceRelay: forceRelay,
  33. connToken: connToken,
  34. isTerminal: true,
  35. );
  36. _connections[peerId] = ffi;
  37. _connectionRefCount[peerId] = 1;
  38. // Register the FFI instance with Get for dependency injection
  39. Get.put<FFI>(ffi, tag: 'terminal_$peerId');
  40. debugPrint('[TerminalConnectionManager] New connection created. Total connections: ${_connections.length}');
  41. return ffi;
  42. }
  43. /// Release a connection reference
  44. static void releaseConnection(String peerId) {
  45. final refCount = _connectionRefCount[peerId] ?? 0;
  46. debugPrint('[TerminalConnectionManager] Releasing connection for peer $peerId. Current ref count: $refCount');
  47. if (refCount <= 1) {
  48. // Last reference, close the connection
  49. final ffi = _connections[peerId];
  50. if (ffi != null) {
  51. debugPrint('[TerminalConnectionManager] Closing connection for peer $peerId (last reference)');
  52. ffi.close();
  53. _connections.remove(peerId);
  54. _connectionRefCount.remove(peerId);
  55. Get.delete<FFI>(tag: 'terminal_$peerId');
  56. }
  57. } else {
  58. // Decrement reference count
  59. _connectionRefCount[peerId] = refCount - 1;
  60. debugPrint('[TerminalConnectionManager] Connection still in use. New ref count: ${_connectionRefCount[peerId]}');
  61. }
  62. }
  63. /// Check if a connection exists for a peer
  64. static bool hasConnection(String peerId) {
  65. final ffi = _connections[peerId];
  66. return ffi != null && !ffi.closed;
  67. }
  68. /// Get existing connection without creating new one
  69. static FFI? getExistingConnection(String peerId) {
  70. return _connections[peerId];
  71. }
  72. /// Get connection count for debugging
  73. static int getConnectionCount() => _connections.length;
  74. /// Get terminal count for a peer
  75. static int getTerminalCount(String peerId) => _connectionRefCount[peerId] ?? 0;
  76. /// Get service ID for a peer
  77. static String? getServiceId(String peerId) => _serviceIds[peerId];
  78. /// Set service ID for a peer
  79. static void setServiceId(String peerId, String serviceId) {
  80. _serviceIds[peerId] = serviceId;
  81. debugPrint('[TerminalConnectionManager] Service ID for $peerId: $serviceId');
  82. }
  83. }