import 'dart:async'; import 'dart:isolate'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import 'package:web_socket_channel/status.dart' as status; import 'package:network_info_plus/network_info_plus.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import '../utils/web_socket_server.dart'; class WebSocketWidget extends StatefulWidget { @override _WebSocketWidgetState createState() => _WebSocketWidgetState(); } class _WebSocketWidgetState extends State { WebSocketChannel? _channel; TextEditingController _controller = TextEditingController(); TextEditingController _urlController = TextEditingController(text: 'ws://localhost:8080'); List _messages = []; Isolate? _serverIsolate; bool _isServerRunning = false; String? _localIpAddress; @override void initState() { super.initState(); _getLocalIpAddress().then((ip) { setState(() { _localIpAddress = ip; _urlController.text = 'ws://$_localIpAddress:8080'; }); }); } Future _getLocalIpAddress() async { if (kIsWeb) { return '127.0.0.1'; // Web does not support getting the local IP address } if (Platform.isAndroid || Platform.isIOS) { final info = NetworkInfo(); String? ip = await info.getWifiIP(); return ip ?? '127.0.0.1'; // Fallback to localhost if no IP is found } for (var interface in await NetworkInterface.list()) { for (var addr in interface.addresses) { if (addr.type == InternetAddressType.IPv4 && !addr.isLoopback) { return addr.address; } } } return '127.0.0.1'; // Fallback to localhost if no IP is found } void _startServer() async { final receivePort = ReceivePort(); _serverIsolate = await Isolate.spawn(webSocketServer, receivePort.sendPort); receivePort.listen((message) { print(message); setState(() { _isServerRunning = true; }); }); } void _stopServer() { _serverIsolate?.kill(priority: Isolate.immediate); setState(() { _isServerRunning = false; }); } void _joinWebSocket() { if (_channel != null) { _channel!.sink.close(); } setState(() { _channel = WebSocketChannel.connect(Uri.parse(_urlController.text)); _channel!.stream.listen((message) { setState(() { _messages.add(message); }); }); }); } void _sendMessage(String message) { if (_channel != null) { _channel!.sink.add(message); setState(() { _messages.add('You: $message'); // Display the sent message }); } } void _closeConnection() { if (_channel != null) { _channel!.sink.close(status.goingAway); setState(() { _channel = null; _messages.clear(); }); } } @override void dispose() { _closeConnection(); _stopServer(); super.dispose(); } @override Widget build(BuildContext context) { // force portrait mode SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); return Scaffold( appBar: AppBar( title: Text('WebSocket Demo'), actions: [ IconButton( icon: Icon(Icons.close), onPressed: _closeConnection, ), ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ if (!_isServerRunning) ElevatedButton( onPressed: _startServer, child: Text('Start WebSocket Server'), ) else ElevatedButton( onPressed: _stopServer, child: Text('Stop WebSocket Server'), ), SizedBox(height: 10), if (_localIpAddress != null) Text('Server URL: ws://$_localIpAddress:8080'), SizedBox(height: 10), TextField( controller: _urlController, decoration: InputDecoration(labelText: 'WebSocket URL'), onSubmitted: (value) => _joinWebSocket(), ), SizedBox(height: 10), ElevatedButton( onPressed: _joinWebSocket, child: Text('Join WebSocket'), ), SizedBox(height: 10), Expanded( child: ListView.builder( itemCount: _messages.length, itemBuilder: (context, index) { return ListTile( title: Text(_messages[index]), ); }, ), ), TextField( controller: _controller, decoration: InputDecoration(labelText: 'Send a message'), onSubmitted: (text) { _sendMessage(text); _controller.clear(); }, ), ], ), ), ); } }