I am struggling how to implement websockets
autoreconnect in flutter. I use web_socket_channel, however, the plugin just wraps dart.io WebSocket, hence any solution based on WebSocket
class will work for me as well.
I already figured out, how to catch the socket disconnection, see the code snippet below:
try {
_channel = IOWebSocketChannel.connect(
wsUrl,
);
///
/// Start listening to new notifications / messages
///
_channel.stream.listen(
_onMessageFromServer,
onDone: () {
debugPrint('ws channel closed');
},
onError: (error) {
debugPrint('ws error $error');
},
);
} catch (e) {
///
/// General error handling
/// TODO handle connection failure
///
debugPrint('Connection exception $e');
}
I was thinking to call IOWebSocketChannel.connect
from within onDone
, however, this leads to a kind of infinite loop - since I have to close the _channel
prior calling connect
again, this on its turn calls onDone
again and so on.
Any help would be greatly appreciated!
webSockets are implemented as follows: Client makes HTTP request to server with "upgrade" header on the request. If server agrees to the upgrade, then client and server exchange some security credentials and the protocol on the existing TCP socket is switched from HTTP to webSocket.
To send a message through the WebSocket connection you call the send() method on your WebSocket instance; passing in the data you want to transfer. socket. send(data); You can send both text and binary data through a WebSocket.
Connect to a WebSocket server The web_socket_channel package provides the tools you need to connect to a WebSocket server. The package provides a WebSocketChannel that allows you to both listen for messages from the server and push messages to the server. In Flutter, use the following line to create a WebSocketChannel that connects to a server:
What is the WebSocket API? According to Mozilla, the WebSocket API is “an advanced technology that makes it possible to open a two-way interactive communication session between the user’s browser and a server… you can send messages to a server and receive event-driven responses without having to poll the server for a reply.”
Connect to a WebSocket server 2. Listen for messages from the server 3. Send data to the server 4. Close the WebSocket connection In addition to normal HTTP requests, you can connect to servers using WebSockets . WebSockets allow for two-way communication with a server without polling.
The StreamBuilder widget connects to a Stream and asks Flutter to rebuild every time it receives an event using the given builder () function. 3. Send data to the server
With the package:web_socket_channel (IOWebSocketChannel) there is not any way in order to implement reconnection for the socket connections. But you can use WebSocket class in order to implement a reconnectable connection.
You can implement the WebSocket channel and then broadcast messages with StreamController class. Working example:
import 'dart:async';
import 'dart:io';
class NotificationController {
static final NotificationController _singleton = new NotificationController._internal();
StreamController<String> streamController = new StreamController.broadcast(sync: true);
String wsUrl = 'ws://YOUR_WEBSERVICE_URL';
WebSocket channel;
factory NotificationController() {
return _singleton;
}
NotificationController._internal() {
initWebSocketConnection();
}
initWebSocketConnection() async {
print("conecting...");
this.channel = await connectWs();
print("socket connection initializied");
this.channel.done.then((dynamic _) => _onDisconnected());
broadcastNotifications();
}
broadcastNotifications() {
this.channel.listen((streamData) {
streamController.add(streamData);
}, onDone: () {
print("conecting aborted");
initWebSocketConnection();
}, onError: (e) {
print('Server error: $e');
initWebSocketConnection();
});
}
connectWs() async{
try {
return await WebSocket.connect(wsUrl);
} catch (e) {
print("Error! can not connect WS connectWs " + e.toString());
await Future.delayed(Duration(milliseconds: 10000));
return await connectWs();
}
}
void _onDisconnected() {
initWebSocketConnection();
}
}
Because the notification controller returns a singleton instance, then there will be always one Socket connection between the server and device. And with the broadcast method of StreamController, we can share the data sent by Websocket between multiple consumers
var _streamController = new NotificationController().streamController;
_streamController.stream.listen(pushNotifications);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With