Comments (36)
Something like this should work :
void initState(){
super.initState();
listenWs();
}
listenWs(){
widget.channel.stream.listen((onData){
final data = json.decode(onData);
print(data);
},onDone: (){
reConnectWs();
}
);
}
reConnectWs(){
final token = prefs.token;
Future.delayed(Duration(milliseconds: 1000)).then((_){
widget.channel = IOWebSocketChannel.connect(WS_URL);
listenWs();
});
}
Hope it helps,
Thanks
from web_socket_channel.
@phamnhuvu-dev I can not do this if your app goes back from background...... cause at that time the websocket already closed.
What users really needs, is simply check if current connect is alive or not
from web_socket_channel.
@mrleesin Obviously the dart team does not notice this problem, they claimed they provide a way which is detect the stream is exit or not, but this way not properly in all situation.................
I have waiting the problem to solve for about twenty years............
from web_socket_channel.
you can use dart:io
like this
class MessageUtils {
static WebSocket _webSocket;
static num _id = 0;
static void connect() {
Future<WebSocket> futureWebSocket =
WebSocket.connect(Api.WS_URL + "/leyan");// Api.WS_URL 为服务器端的 websocket 服务
futureWebSocket.then((WebSocket ws) {
_webSocket = ws;
_webSocket.readyState;
// 监听事件
void onData(dynamic content) {
_id++;
_sendMessage("收到");
_createNotification("新消息", content + _id.toString());
}
_webSocket.listen(onData,
onError: (a) => print("error"), onDone: () => print("done"));
});
}
static void closeSocket() {
_webSocket.close();
}
// 向服务器发送消息
static void _sendMessage(String message) {
_webSocket.add(message);
}
// 手机状态栏弹出推送的消息
static void _createNotification(String title, String content) async {
await LocalNotifications.createNotification(
id: _id,
title: title,
content: content,
onNotificationClick: NotificationAction(
actionText: "some action",
callback: _onNotificationClick,
payload: "接收成功!"),
);
}
static _onNotificationClick(String payload) {
LocalNotifications.removeNotification(_id);
_sendMessage("消息已被阅读");
}
}
from web_socket_channel.
@sachin052 this is unrelated to this issue. What we want is when apps goes back from background, disconnect signal can be correctly detected by this lib.
from web_socket_channel.
@cindyqin2015 what do u mean by that? That sounds a little complicated. Indeed, listen closeCode
only works when app alive and close connection from server, but what we want is app goes back from background then it doesn't work.
At least, it doesn't correctly detected if connection actually disconnected.
currently I don't know what's the simplest and best way to do this.
As for @Katekko provides dart::io, that is not I want, it can not have a StreamController which I can listen messages arrive callback inside another page.
If web_socket_channel can provides a way to fix this, that would be great!
from web_socket_channel.
Hi guys, was suffering from that too but I modified @TomLiu-GitHub 's codes (which was a great reference) to the following:
//// Initialised A Task Upon Loading
SOME_INIT_FUNCTION(){
// Initialise the task
HandleWSConnection();
}
//// The Task Itself, which periodically checks if _websocket is "null"
HandleWSConnection(){
print("Handle WS Connection");
// Send Heartbeat
if (
_webSocket != null &&
_webSocket.readyState == WebSocket.open
) {
WSSendHBTMessage();
}
// Request Connection
else {
ConnectWS();
}
// Set next interval action
Future.delayed(Duration( milliseconds: WS_INTERVAL ), HandleWSConnection);
}
//// Create the Connection
Future<void> ConnectWS() async{
print("Connect WS");
//// Do not if already connected
if (
_webSocket != null &&
(
_webSocket.readyState == WebSocket.open ||
_webSocket.readyState == WebSocket.connecting
)
){
print("WS already connected or connecting");
return;
}
Future<WebSocket> futureWebSocket = WebSocket.connect( 'ws://$_host:$_port' );
futureWebSocket.then( ( WebSocket webSocket ){
_webSocket = webSocket;
webSocket.listen(
OnWSData,
onError: ( error ){
print( "There was an error." );
print( error );
},
onDone: (){
print( "WS Closed" );
_webSocket = null;
},
cancelOnError: true,
);
});
}
I use this the detect if the connection is made. If there is a disconnection, I set the _websocket to "null" then periodically try to reconnect back.
I hope it helps someone.
from web_socket_channel.
The same question!
from web_socket_channel.
listen onDone: () {
print("Close WS");
}
I tested when I shutdown server, the socket channel on the client(Flutter or AngularDart) is called onDone.
from web_socket_channel.
We definetly needs some way to check the current connectivity. +1 for this
from web_socket_channel.
Pull requests welcome.
from web_socket_channel.
The same question!
from web_socket_channel.
@kevmoo Any updates on this? Or does there any alternative package of websocket as flutter community becomes larger?
from web_socket_channel.
@TomLiu-GitHub Does this can keep listening when app goes back to home? (both Android and iOS). If not, does it can detect ws connection closed?
from web_socket_channel.
you can use dart:io
like this
class MessageUtils { static WebSocket _webSocket; static num _id = 0; static void connect() { Future<WebSocket> futureWebSocket = WebSocket.connect(Api.WS_URL + "/leyan");// Api.WS_URL 为服务器端的 websocket 服务 futureWebSocket.then((WebSocket ws) { _webSocket = ws; _webSocket.readyState; // 监听事件 void onData(dynamic content) { _id++; _sendMessage("收到"); _createNotification("新消息", content + _id.toString()); } _webSocket.listen(onData, onError: (a) => print("error"), onDone: () => print("done")); }); } static void closeSocket() { _webSocket.close(); } // 向服务器发送消息 static void _sendMessage(String message) { _webSocket.add(message); } // 手机状态栏弹出推送的消息 static void _createNotification(String title, String content) async { await LocalNotifications.createNotification( id: _id, title: title, content: content, onNotificationClick: NotificationAction( actionText: "some action", callback: _onNotificationClick, payload: "接收成功!"), ); } static _onNotificationClick(String payload) { LocalNotifications.removeNotification(_id); _sendMessage("消息已被阅读"); } }
Works like a charm, ty
@TomLiu-GitHub Does this can keep listening when app goes back to home? (both Android and iOS). If not, does it can detect ws connection closed?
That's keep the connection open 'cause all the attributes and methods are static, so it's means that you have only one class, u can't instantiate another one... If the server force the disconnect u can check with that, I guess
from web_socket_channel.
Does if (channel.closeCode != null)
solve the issue for you?
from web_socket_channel.
@natebosch Does it work? I mean there are some methods call it but actually it not worked.
from web_socket_channel.
Does it work?
I would expect so, it's tested at least
I mean there are some methods call it but actually it not worked.
Doesn't work how? Can you provide a reproduction case?
from web_socket_channel.
There have no way to detect disconnect of socket otherwise add ping pong. But I have tried this lib, ping pong is not working.
There have no response issues since disconnect status can't be detected.
For example: if app go to background long time or keep foreground long time, but not access server. when user back to app, app will think socket still alive, since OnDone is not be called and closeCode is always Null, then app want to send package to server, no response in this case.
So I add a 1 min timeout timer to fix this. if no package send/receive, after 1 mins, app will call _channel?.sink.close(socketChannelStatus.goingAway); to close socket.
from web_socket_channel.
I know it doesn't work, and there no way work by using lib. But I found an alternative way to resolve those disconnect unknown issues, and share here for see whether can help someone.
from web_socket_channel.
working code for me
if (channel==null) {
channel = IOWebSocketChannel.connect(url);
listenChannelStream();
}
else{
channel.sink.close(status.goingAway);
channel = IOWebSocketChannel.connect(url);
listenChannelStream();
}
from web_socket_channel.
@phamnhuvu-dev I can not do this if your app goes back from background...... cause at that time the websocket already closed.
What users really needs, is simply check if current connect is alive or not
@jinfagang could you please describe your problem in details?Be better with procedure in details.I have tried the websocket channel as your procedure ,the channel could keep active in background in my andoird phone.And then, i tried the network factor.When the demo being running,i closed my wifi,and the onDone method was called.It seems nothing wrong to happen.
from web_socket_channel.
@baotoushashou Can u you share your demo?
from web_socket_channel.
So when your apps goes back from background, the method onClosed
can be run?
from web_socket_channel.
@baotoushashou Can u you share your demo?
the connection was still on active
from web_socket_channel.
@jinfagang so,how to reappear your problem?
from web_socket_channel.
@baotoushashou Turn off your wifi or cut down your sever listening
from web_socket_channel.
@jinfagang i have tried it.Nothing wrong with it.turn off my wifi.The log show reconnect.and then the connection recreated.
from web_socket_channel.
Please show me your environment and procedures in details. So I could reappear your problem.
from web_socket_channel.
@baotoushashou Would u share your code on github so that I can have a try?
from web_socket_channel.
@jinfagang of course
///连接
void connect() {
_doConnect();
print("websocket 连接。。。");
}
void _doConnect() {
if (this._channel != null && this._state != WebSocketChannelState.closed) {
close();
}
this._channel = IOWebSocketChannel.connect(
WS_ADDRESS,
pingInterval: Duration(
seconds: 1,
),
);
_state = WebSocketChannelState.connecting;
this._channel.stream.listen(onReceiveData,
onDone: onClosed, onError: onError, cancelOnError: false);
}
///收到数据
void onReceiveData(data) {
Protocol protocol = Protocol(data);
ProtocolManager().dispatch(protocol);
print("websocket receive protocol:${protocol.prtId} data:$data");
}
///连接断开,进行重连
void onClosed() {
print("websocket 已断开");
new Future.delayed(Duration(seconds: 1), () {
print("websocket 重连。。。");
_doConnect();
});
}
void onError(err, StackTrace stackTrace) {
print("websocket 出错:" + err.toString());
if (stackTrace != null) {
print(stackTrace);
}
}
void close() {
this._channel.sink.close();
this._state = WebSocketChannelState.closed;
}
Please igore the state of websocket managing.I'm tring to manage the state of websocket channel. So it's a tempprary and half-baked version.
from web_socket_channel.
@jinfagang Have u solved your problems?I tried the web_socket_channel and my code in the LTE. I found something wrong, maybe it's a bug of the channel. The thing is that When the channel connecting with LTE, it is ok. But later I have closen the LTE. The stranger thing appeared. The onDone was not called. Is it the same as your problem? I think it 's a bug of the web_socket_channel.
from web_socket_channel.
@baotoushashou I believe it is so. I previous not notice the differences between LTE and wifi.
But problem actually exists.
from web_socket_channel.
@jinfagang The problem above in my real phone did not exist. Just in simulator.
from web_socket_channel.
Can be helpful: https://stackoverflow.com/questions/55503083/flutter-websockets-autoreconnect-how-to-implement/62095514#62095514
from web_socket_channel.
https://stackoverflow.com/a/68549605/13713269
you can refer this
from web_socket_channel.
Related Issues (20)
- web_socket_channel ^2.4.2依然没有支持web0.3.0 HOT 1
- Socket connection for self signed certificate
- While I can introduce web_socket_channel into dart, iOS won't be able to call this package
- Web version websocket doesn't work, but ios does HOT 4
- websocket is not connecting
- Add feature HOT 1
- Auto invoke onDown method to close websocket. HOT 1
- 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
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.