desktop push
This commit is contained in:
196
lib/backend/modules/networking.dart
Normal file
196
lib/backend/modules/networking.dart
Normal file
@@ -0,0 +1,196 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:network_info_plus/network_info_plus.dart';
|
||||
import 'package:shelf/shelf.dart';
|
||||
import 'package:shelf/shelf_io.dart' as io;
|
||||
import 'package:shelf_web_socket/shelf_web_socket.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
import 'package:bus_infotainment/backend/modules/info_module.dart';
|
||||
import 'package:bus_infotainment/utils/delegates.dart';
|
||||
|
||||
class NetworkingModule extends InfoModule {
|
||||
// Host websocket server
|
||||
String host = "ws://0.0.0.0:8080";
|
||||
HttpServer? _server;
|
||||
WebSocketChannel? _channel;
|
||||
|
||||
// Store connected WebSocket channels
|
||||
final List<WebSocketChannel> _connectedClients = [];
|
||||
|
||||
EventDelegate<String>? onMessageReceived = EventDelegate();
|
||||
|
||||
NetworkingModule() {
|
||||
_refresh();
|
||||
refreshTimer();
|
||||
}
|
||||
|
||||
Future<bool> startWebSocketServer() async {
|
||||
try {
|
||||
var handler = webSocketHandler((WebSocketChannel webSocket) {
|
||||
_connectedClients.add(webSocket); // Add the client to the list
|
||||
print('Client connected: ${webSocket}'); // Log client connection
|
||||
|
||||
webSocket.stream.listen((message) {
|
||||
// Handle messages from the client here
|
||||
print('Received message: $message');
|
||||
|
||||
// Forward message to all clients except the sender
|
||||
for (var client in _connectedClients) {
|
||||
if (client != webSocket) {
|
||||
client.sink.add(message);
|
||||
}
|
||||
}
|
||||
|
||||
_onMessageReceived(message);
|
||||
}, onDone: () {
|
||||
_connectedClients.remove(webSocket); // Remove client on disconnect
|
||||
print('Client disconnected: ${webSocket}'); // Log client disconnection
|
||||
});
|
||||
});
|
||||
|
||||
_server = await io.serve(handler, InternetAddress.anyIPv4, 8080);
|
||||
print('WebSocket server started at ${_server?.address.address}:${_server?.port}');
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Failed to start WebSocket server: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool stopWebSocketServer() {
|
||||
if (_server == null) {
|
||||
throw Exception('WebSocket server is not running');
|
||||
}
|
||||
|
||||
try {
|
||||
for (var client in _connectedClients) {
|
||||
client.sink.close();
|
||||
}
|
||||
_connectedClients.clear();
|
||||
_server?.close(force: true);
|
||||
_server = null;
|
||||
print('WebSocket server stopped');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Failed to stop WebSocket server: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> connectToWebSocketServer(String url) async {
|
||||
try {
|
||||
_channel = await WebSocketChannel.connect(Uri.parse(url));
|
||||
_channel?.stream.listen((message) {
|
||||
// Handle messages from the server here
|
||||
print('Received message from server: $message');
|
||||
_onMessageReceived(message);
|
||||
});
|
||||
|
||||
print('Connected to WebSocket server at $url');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Failed to connect to WebSocket server: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool disconnectFromWebSocketServer() {
|
||||
if (_channel == null) {
|
||||
throw Exception('No active WebSocket connection');
|
||||
}
|
||||
|
||||
try {
|
||||
_channel?.sink.close();
|
||||
_channel = null;
|
||||
print('Disconnected from WebSocket server');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Failed to disconnect from WebSocket server: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool sendMessage(String message) {
|
||||
|
||||
// If hosting a server, send message to all clients
|
||||
if (_server != null) {
|
||||
return sendMessageToClients(message);
|
||||
}
|
||||
|
||||
if (_channel == null) {
|
||||
throw Exception('No active WebSocket connection');
|
||||
}
|
||||
|
||||
try {
|
||||
_channel?.sink.add(message);
|
||||
print('Sent message: $message');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Failed to send message: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool sendMessageToClients(String message) {
|
||||
if (_connectedClients.isEmpty) {
|
||||
print('No clients connected');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
for (var client in _connectedClients) {
|
||||
client.sink.add(message);
|
||||
}
|
||||
print('Sent message to all clients: $message');
|
||||
return true;
|
||||
} catch (e) {
|
||||
print('Failed to send message to clients: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void _onMessageReceived(String message) {
|
||||
// Notify all listeners that a message has been received.
|
||||
onMessageReceived?.trigger(message);
|
||||
}
|
||||
|
||||
// Useful boilerplate
|
||||
String _localIP = "";
|
||||
String get localIP => _localIP;
|
||||
|
||||
Timer refreshTimer() => Timer.periodic(const Duration(seconds: 10), (timer) {
|
||||
if (kIsWeb) return;
|
||||
_refresh();
|
||||
});
|
||||
|
||||
Future<void> _refresh() async {
|
||||
print("Refreshing network info...");
|
||||
{
|
||||
// Update the local IP address
|
||||
|
||||
// First try NetworkInfo
|
||||
_localIP = (await NetworkInfo().getWifiIP()) ?? "";
|
||||
|
||||
// If null, try NetworkInterface
|
||||
// Only look for ethernet. Wifi would have been found by NetworkInfo
|
||||
if (_localIP.isEmpty) {
|
||||
for (var interface in await NetworkInterface.list()) {
|
||||
if (!interface.name.toLowerCase().contains("eth") || interface.name.contains(" ")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var addr in interface.addresses) {
|
||||
print('Interface ${interface.name} has address ${addr.address}');
|
||||
if (addr.type == InternetAddressType.IPv4 && !addr.isLoopback) {
|
||||
_localIP = addr.address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user