Comments (42)
This is needed to handle reconnects.
With this package I have no idea how to:
- Handle reconnects
- Know the state of the connection.
from web_socket_channel.
I don't understand how you're supposed to use a websocket package that is meant for mobile devices that has no way to handle disconnects (so you can reconnect). That's not something that you would ever expose in a production ready product. One disconnect because you go under a bridge, and that's it?
from web_socket_channel.
The stream will emit a done event when the socket has disconnected--is that not enough?
from web_socket_channel.
2022 and there is no solid way yet ?!)
from web_socket_channel.
@nex3 , when server interface is going away stream didn't emit a done event! and this is a bug.
from web_socket_channel.
@nailgilaziev that sounds like a bug with dart:io
's implementation. I suggest finding a reproduction that just uses dart:io
's WebSocket
class and filing a bug against the dart-lang/sdk repo.
from web_socket_channel.
@Allan-Nava
I do something like this
WebSocket socket;
void _onDisconnected() {
print('Disconnected');
if (socket != null) {
socket.close();
}
socket = null;
_tryConnect();
}
void _tryConnect() {
WebSocket.connect(url).then((ws) {
socekt = ws;
socket.listen(
(dynamic message) {
print(message)
},
onDone: _onDisconnected,
onError: (dynamic error) => _onDisconnected(),
);
socket.done.then((dynamic _) => _onDisconnected());
});
}
from web_socket_channel.
Any recent updates on this request? It is something really required in case you are going after mobile app on production - see #40 as well...
from web_socket_channel.
@Allan-Nava; wrap connection initialization in a function and call it every time the onDone event is triggered
from web_socket_channel.
Hi everyone, I got a workaround. And it works (Did not test is very hard).
I am using flutter package: https://pub.dev/packages/connectivity
So with this package, I can listen to connection state changes like this :
StreamSubscription<ConnectivityResult> _connectivitySubscription;
_connectivitySubscription = Connectivity()
.onConnectivityChanged.listen((ConnectivityResult result) {
if (result == ConnectivityResult.wifi ||
result == ConnectivityResult.mobile) {
_tryConnect();
}
});
and then as above mentioned _tryConnect Function :
void _tryConnect() {
final channel = IOWebSocketChannel.connect(
"url");
channel.sink.add("connected");
channel.stream.listen(
(message) {
print(message);
},
onError: (dynamic error) => print(error),
);
}
In this way, if connection drops then the _connectivitySubscription will change to none and when back online which will result in wifi or mobile. it will call _tryConnect() and connect. Open to suggestions. (Peace)
from web_socket_channel.
Sorry, I'm no longer on the Dart team and no longer a maintainer of this package.
from web_socket_channel.
2024 and there is no solid way yet ?!)
from web_socket_channel.
Hi, I am new to websocket and there are really not much flutter websocket articles online. Can anyone please show me how to do reconnection in flutter when the connection is lost somehow (for example, the server machine restarts). When I search the keywords flutter websocket reconnect
, I find nothing related in google except this issue. Thank you very much.
from web_socket_channel.
@Allan-Nava
I do something like thisWebSocket socket; void _onDisconnected() { print('Disconnected'); if (socket != null) { socket.close(); } socket = null; _tryConnect(); } void _tryConnect() { WebSocket.connect(url).then((ws) { socekt = ws; socket.listen( (dynamic message) { print(message) }, onDone: _onDisconnected, onError: (dynamic error) => _onDisconnected(), ); socket.done.then((dynamic _) => _onDisconnected()); }); }
I've recently tried doing something similar. My situation is a little different though - I need to know when a particular machine is turned off, in this case there does not seem to be anything emitted in any particular way (neither the socket or the stream emit onDone or onError) until I turn the machine back on, then the connection is reset and errors happen.
I need to know if the TCP socket is still live without sending a command over the socket to get the machine to respond.
from web_socket_channel.
@hogdamian You can implement auto reconnect by modifying the code of @Lyuzonggui slightly because the send
method call initCommunication()
method, this would mostly fail if the send
method is invoked frequently causing a lot of socket recreations.
import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/io.dart';
WebSocketsHandler sockets = new WebSocketsHandler();
const String _SERVER_ADDRESS = "ws://127.0.0.1:6800/jsonrpc";
class WebSocketsHandler {
static final WebSocketsHandler _sockets = new WebSocketsHandler._internal();
factory WebSocketsHandler() => _sockets;
WebSocketsHandler._internal();
IOWebSocketChannel _channel;
bool _disconnected = true;
int _times = 0;
ObserverList<Function> _listeners = new ObserverList<Function>();
initCommunication() async {
reset();
try {
_times += 1;
debugPrint("try to connect $_times time(s)");
_channel = new IOWebSocketChannel.connect(_SERVER_ADDRESS);
_disconnected = false;
_channel.stream.listen(
_onReceptionOfMessage,
onError:(error) {/* debugPrint(error); */},
onDone: () {
debugPrint("Receive done event.");
_disconnected = true;
// add delay here
Future.delayed(const Duration(seconds: 1))
.then((value) => initCommunication());
});
} catch (e) {/** */}
}
reset() {
if (_channel != null) {
if (_channel.sink != null) {
_channel.sink.close();
_disconnected = true;
}
}
}
List<String> failedKeys = [];
send(String message) {
///check connection before send message
if (_disconnected) {
// add to list here
failedKeys.add(message);
}
if (_channel != null) {
if (_channel.sink != null && _disconnected == false) {
_channel.sink.add(message);
}
// add them later
}
}
addListener(Function callback) {
_listeners.add(callback);
}
removeListener(Function callback) {
_listeners.remove(callback);
}
_onReceptionOfMessage(message) {
_disconnected = false;
_listeners.forEach((Function callback) {
callback(message);
});
}
}
And create a timer that will fetch the missing keys:
Timer.periodic(const Duration(seconds: 5), (timer) {
if (failedKeys.isEmpty) return;
if (kDebugMode) print("Update failed key ${failedKeys.length}");
for (var entry in failedKeys) {
channel!.sink.add(entry.websocketData);
}
Just call the initCommunication method in the main.dart method.
Regards,
William
from web_socket_channel.
@nex3 Are there any plans to ever implement the readyState?
It is clearly stated that several people would need this, and I couldn't identify any problem which would block this from being implemented.
Would a pull request help?
from web_socket_channel.
What do you mean by "the state", exactly?
from web_socket_channel.
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket#Ready_state_constants
from web_socket_channel.
An event is also needed for each state.
from web_socket_channel.
@dionjwa What package do you use now?
from web_socket_channel.
@AlexeySemigradsky This is my first foray into using flutter. I want to write a cross-platform app, where the core requirement is a persistent websocket connection. It doesn't look like flutter is ready to support this as yet.
from web_socket_channel.
@nex3 So what about this feature? Should I wait for its implementation?
from web_socket_channel.
I started working on the Socket.IO plugin for the Flutter instead of using web_socket_channel
.
from web_socket_channel.
Because WebSocketChannel
needs to work on both the Dart VM and in the browser, the best we can do is expose the subset of APIs supported on both platforms. We can (and probably should) expose a readyState
getter, but because dart:io
's WebSocket
class doesn't provide any events when that state changes there's no way for this package to support them either.
from web_socket_channel.
@nex3 Somehow that wasn't clear. Yes, that would definitely be sufficient. Thank you!
from web_socket_channel.
I think that is a lib bug(lack of implementation), because I rewrite my code to use pure dart:io
If I use this
done → Future
Return a future which is completed when the StreamSink is finished.
read-only, inherited
https://api.dartlang.org/stable/1.24.3/dart-io/WebSocket-class.html
then error event exist
from web_socket_channel.
Can you produce a minimal reproduction, including server code, where dart:io
emits a done event but this package does not?
from web_socket_channel.
My server code running on kotlin - ktor. repo But is does not matter. You can use public ehho server. ws://echo.websocket.org
What matter is that you need emulate bad network condition. For this I use Network Link Conditioner with 100% loss profile.
Full code listings:
channel_example code is a tutorial example code from cookbook but with two difference:
- added pingInterval to connect method
pingInterval: Duration(seconds: 10)
- print lines for debugging in
StreamBuilder
dart io example code contains with handy reconnect functionality and other debug stuffs, but main thing is next:
ws.done.then((v) {
setState(() {
ex = new Exception("Connection is done with v=$v");
timeprint("DONE");
});
});
This lambda called when connection is down. Not a lambda for onDone
parameter for `ws.listen()' function.
What the behaviour when we see the difference between channel package and dart:io code:
- Firstly, we connected to ws server and try to send and receive messages - both works fine.
- Then we switch on Network Link Conditioner tool with 100% loss profile.
- wait
And here the difference come. Because we specife in both code that we use pingInterval
after around 20sec dart:io code call done
lambda. But channel example don't call anything, no matter how you wait.
from web_socket_channel.
In my case, I do not receive 'onDone' message or anything for that matter if the mobile loses data connection. Will it be possible for me to ask the IOWebSocketChannel if it is still connected every 5 seconds or so? I imagine it will know if it is following WebSocket protocol because it won't be receiving frames. Thanks!
from web_socket_channel.
Is possible to reconnect after the websocket is die?
from web_socket_channel.
@Allan-Nava; wrap connection initialization in a function and call it every time the onDone event is triggered
Can you please give me an example, thanks ❤️
from web_socket_channel.
@Allan-Nava
I do something like thisWebSocket socket; void _onDisconnected() { print('Disconnected'); if (socket != null) { socket.close(); } socket = null; _tryConnect(); } void _tryConnect() { WebSocket.connect(url).then((ws) { socekt = ws; socket.listen( (dynamic message) { print(message) }, onDone: _onDisconnected, onError: (dynamic error) => _onDisconnected(), ); socket.done.then((dynamic _) => _onDisconnected()); }); }
Thanks
from web_socket_channel.
I'm using this solution and works for me.
https://gist.github.com/pyzenberg/4037e11627a8cac1c442183cc7cf172a
from web_socket_channel.
Any news on this? I implemented a WebSocket sub protocol (WAMP) with dart (+flutter) and it seems impossible to handle reconnects in a nice way. I'll end up to hack something in combination with custom Ping/Pongs and Bad state: No element
errors to make this work with WebSockets:io and Sockets:io.
WebSockets:html works as expected as this is the browser implementation.
The issues I experience (so far) are:
- server closed connection, but all socket client states are connected, the stream is not closing either
- pingInterval in WebSockets:io does weired things - The server just does not receive anything
- await WebSocket.connect(_url, protocols: [_serializerType]) -> runs forever
- I would love to set SO_KEEPALIVE in Socket, I have no Idea how to?
from web_socket_channel.
Can be helpful: https://stackoverflow.com/questions/55503083/flutter-websockets-autoreconnect-how-to-implement/62095514#62095514
from web_socket_channel.
I make GUI app for aria2, same problem, when I read this:
https://www.didierboelens.com/2018/06/web-sockets-build-a-real-time-game/
so my way is, Singleton handler, check connection befor send message.it works fine
import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/io.dart';
WebSocketsHandler sockets = new WebSocketsHandler();
const String _SERVER_ADDRESS = "ws://127.0.0.1:6800/jsonrpc";
class WebSocketsHandler {
static final WebSocketsHandler _sockets = new WebSocketsHandler._internal();
factory WebSocketsHandler() => _sockets;
WebSocketsHandler._internal();
IOWebSocketChannel _channel;
bool _disconnected = true;
int _times = 0;
ObserverList<Function> _listeners = new ObserverList<Function>();
initCommunication() async {
reset();
try {
_times += 1;
debugPrint("try to connect $_times time(s)");
_channel = new IOWebSocketChannel.connect(_SERVER_ADDRESS);
_disconnected = false;
_channel.stream.listen(
_onReceptionOfMessage,
onError:(error) {/* debugPrint(error); */},
onDone:(){_disconnected = true;});
} catch (e) {/** */}
}
reset() {
if (_channel != null) {
if (_channel.sink != null) {
_channel.sink.close();
_disconnected = true;
}
}
}
send(String message) {
///check connection before send message
if (_disconnected) {
initCommunication();
}
if (_channel != null) {
if (_channel.sink != null && _disconnected == false) {
_channel.sink.add(message);
}
}
}
addListener(Function callback) {
_listeners.add(callback);
}
removeListener(Function callback) {
_listeners.remove(callback);
}
_onReceptionOfMessage(message) {
_disconnected = false;
_listeners.forEach((Function callback) {
callback(message);
});
}
}
from web_socket_channel.
People could use the WAMP protocol with my dart client to work with web sockets / sockets to deliver messages. I have implemented all that is needed to handle the states.
from web_socket_channel.
My clients randomly disconnects and i need to find a solution for this.
from web_socket_channel.
@Lyuzonggui I'm not sure I follow. I'm using websockets with flutter web, and it works. But I'm seeing the connection drop I think some times if I close my laptop or minimize chrome. Haven't really characterized fully. But I would love a way to check if the stream is there in the flutter web periodically and reconnect if down. I see your reset() function but I don't see any way this checks if it's down?
reset() {
if (_channel != null) {
if (_channel.sink != null) {
_channel.sink.close();
_disconnected = true;
}
}
}
Is checking for sink being null maybe a check for a connection being gone?
from web_socket_channel.
2022 and there is no solid way yet ?!)
@faganchalabizada seems like this is of very low priority. I guess the problem here is to implement this for all plattforms
from web_socket_channel.
I am still having the same issue.
catching the connect function is not working.
I want to catch the error.
For example "Connection failed"
from web_socket_channel.
IOWebSocketChannel - innerWebSocket - readyState
/// Possible states of the connection.
static const int connecting = 0;
static const int open = 1;
static const int closing = 2;
static const int closed = 3;
from web_socket_channel.
Related Issues (20)
- Specifying 'protocols' (Sec-WebSocket-Protocol header) causes connection to close.
- HTML: When the WebSocket is in a 'pending' state, calling channel.sink.close does not work. HOT 2
- Masking is not cryptographically secure HOT 1
- I tried to connect with localhost 8081 port but its connect with diffrent port HOT 2
- FormatException: Unexpected character
- Simplify the web_socket_channel implementation HOT 5
- Message received in wrong order
- Support MSGPACK HOT 1
- Any problems with WebSocketChannel.connect under iOS 17.5 beta (or earlier)? HOT 3
- 🐛 RangeError (code): Invalid value: Not in inclusive range 3000..4999: 1000 after updating to 3.0.0 from 2.4.0 HOT 6
- Missing tags for 2.4.5 and 3.0.0
- Conflict package build_runner versions HOT 1
- Documentation for the 3.x migration HOT 12
- Unexpected Behavior and Premature Closure when Using web_socket_channel to Connect to WebSocket Server HOT 2
- WebSocket clients using Apple private relay can't connect to WebSocket server
- WebSocketChannel has unexpected close code
- WebSocketChannel close code throws exception
- There is not way to get acknowledgement of sent messages. HOT 1
- WebSocket support custom sni host,when use doh HOT 1
- Should the `ready` future fail if the socket gets closed while not resolved?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from web_socket_channel.