feat: add WebSocket support - real-time notifications in Flutter
This commit is contained in:
86
lib/core/ws_provider.dart
Normal file
86
lib/core/ws_provider.dart
Normal file
@@ -0,0 +1,86 @@
|
||||
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
|
||||
});
|
||||
Reference in New Issue
Block a user