Summary
I have a program using WebSockets in Flutter, the program is fully functional in debug mode, but running the same exact code in release mode causes an error.
Context
The Flutter documentation teaches us how to work with WebSockets.
Let's use consider the official code example to work with WebSockets (I've modified it a bit to display the error in a Text
Widget):
import 'package:flutter/material.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
const title = 'WebSocket Demo';
return const MaterialApp(
title: title,
home: MyHomePage(
title: title,
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
required this.title,
});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final TextEditingController _controller = TextEditingController();
final _channel = WebSocketChannel.connect(
Uri.parse('wss://echo.websocket.events'),
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Form(
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(labelText: 'Send a message'),
),
),
const SizedBox(height: 24),
StreamBuilder(
stream: _channel.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
} else if (snapshot.hasError) {
return Text(snapshot.error.toString());
} else {
return const Text('listening...');
}
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _sendMessage,
tooltip: 'Send message',
child: const Icon(Icons.send),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _sendMessage() {
if (_controller.text.isNotEmpty) {
_channel.sink.add(_controller.text);
}
}
@override
void dispose() {
_channel.sink.close();
_controller.dispose();
super.dispose();
}
}
The problem
If you run the above code snippet on MacOS in debug mode, it will work correctly. However, If you build the app using flutter build macos
, you'll get this error:
SocketException: Failed host lookup: ‘...’ (OS Error: nodename nor servname provided, or not known, errno = 8)
What I tried
-
SocketException: Connection failed (OS Error: Operation not permitted, errno = 1) with flutter app on macOS which said to add this
<key>com.apple.security.network.client</key> <true/>
-
-
ssh: Could not resolve hostname [hostname]: nodename nor servname provided, or not known
Turned off my FireWall.
Made sure there's an active Internet connection.
Question
Why does the above snippet work in Debug mode, but not in release mode when running flutter build macos
?
Note
Running
flutter doctor -v
says "no issues found".