87 lines
2.1 KiB
Dart
87 lines
2.1 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
|
import 'package:web_socket_channel/status.dart' as status;
|
|
|
|
// Estado del WebSocket
|
|
class WSState {
|
|
final bool connected;
|
|
final String? error;
|
|
final dynamic lastMessage;
|
|
|
|
const WSState({
|
|
this.connected = false,
|
|
this.error,
|
|
this.lastMessage,
|
|
});
|
|
|
|
WSState copyWith({
|
|
bool? connected,
|
|
String? error,
|
|
dynamic lastMessage,
|
|
}) {
|
|
return WSState(
|
|
connected: connected ?? this.connected,
|
|
error: error,
|
|
lastMessage: lastMessage ?? this.lastMessage,
|
|
);
|
|
}
|
|
}
|
|
|
|
class WSNotifier extends StateNotifier<WSState> {
|
|
WebSocketChannel? _channel;
|
|
final String baseUrl;
|
|
|
|
WSNotifier(this.baseUrl) : super(const WSState());
|
|
|
|
// Conectar a WebSocket de una dirección
|
|
Future<void> connect(String token, int addressId) async {
|
|
try {
|
|
final wsUrl = baseUrl.replaceFirst('https', 'wss').replaceFirst('http', 'ws');
|
|
final url = Uri.parse('$wsUrl/eta/ws/$addressId');
|
|
|
|
_channel = WebSocketChannel.connect(url);
|
|
|
|
// Escuchar mensajes
|
|
_channel?.stream.listen(
|
|
(message) {
|
|
state = state.copyWith(
|
|
lastMessage: message,
|
|
connected: true,
|
|
error: null,
|
|
);
|
|
},
|
|
onError: (error) {
|
|
state = state.copyWith(
|
|
connected: false,
|
|
error: error.toString(),
|
|
);
|
|
},
|
|
onDone: () {
|
|
state = state.copyWith(connected: false);
|
|
},
|
|
);
|
|
|
|
state = state.copyWith(connected: true, error: null);
|
|
} catch (e) {
|
|
state = state.copyWith(connected: false, error: e.toString());
|
|
}
|
|
}
|
|
|
|
// Enviar mensaje
|
|
void send(String message) {
|
|
if (_channel != null && state.connected) {
|
|
_channel!.sink.add(message);
|
|
}
|
|
}
|
|
|
|
// Desconectar
|
|
void disconnect() {
|
|
_channel?.sink.close(status.goingAway);
|
|
state = state.copyWith(connected: false);
|
|
}
|
|
}
|
|
|
|
final wsProvider = StateNotifierProvider<WSNotifier, WSState>((ref) {
|
|
return WSNotifier('http://localhost:8000'); // Cambiar a URL de producción
|
|
});
|