Code Monkey home page Code Monkey logo

Comments (36)

ramioooz avatar ramioooz commented on August 17, 2024 10

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.

lucasjinreal avatar lucasjinreal commented on August 17, 2024 9

@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.

lucasjinreal avatar lucasjinreal commented on August 17, 2024 5

@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.

TomLiu-GitHub avatar TomLiu-GitHub commented on August 17, 2024 3

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.

lucasjinreal avatar lucasjinreal commented on August 17, 2024 3

@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.

lucasjinreal avatar lucasjinreal commented on August 17, 2024 1

@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.

denewbie avatar denewbie commented on August 17, 2024 1

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.

mrleesin avatar mrleesin commented on August 17, 2024

The same question!

from web_socket_channel.

phamnhuvu-dev avatar phamnhuvu-dev commented on August 17, 2024

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.

shinayser avatar shinayser commented on August 17, 2024

We definetly needs some way to check the current connectivity. +1 for this

from web_socket_channel.

kevmoo avatar kevmoo commented on August 17, 2024

Pull requests welcome.

from web_socket_channel.

TomLiu-GitHub avatar TomLiu-GitHub commented on August 17, 2024

The same question!

from web_socket_channel.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

@kevmoo Any updates on this? Or does there any alternative package of websocket as flutter community becomes larger?

from web_socket_channel.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

@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.

Katekko avatar Katekko commented on August 17, 2024

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

https://stackoverflow.com/questions/21769918/how-do-i-know-if-im-disconnected-from-a-dart-websocket-server

from web_socket_channel.

natebosch avatar natebosch commented on August 17, 2024

Does if (channel.closeCode != null) solve the issue for you?

https://pub.dev/documentation/web_socket_channel/latest/web_socket_channel/WebSocketChannel/closeCode.html

from web_socket_channel.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

@natebosch Does it work? I mean there are some methods call it but actually it not worked.

from web_socket_channel.

natebosch avatar natebosch commented on August 17, 2024

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.

cindyqin2015 avatar cindyqin2015 commented on August 17, 2024

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.

cindyqin2015 avatar cindyqin2015 commented on August 17, 2024

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.

sachin052 avatar sachin052 commented on August 17, 2024

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.

baotoushashou avatar baotoushashou commented on August 17, 2024

@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.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

@baotoushashou Can u you share your demo?

from web_socket_channel.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

So when your apps goes back from background, the method onClosed can be run?

from web_socket_channel.

baotoushashou avatar baotoushashou commented on August 17, 2024

@baotoushashou Can u you share your demo?

the connection was still on active

from web_socket_channel.

baotoushashou avatar baotoushashou commented on August 17, 2024

@jinfagang so,how to reappear your problem?

from web_socket_channel.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

@baotoushashou Turn off your wifi or cut down your sever listening

from web_socket_channel.

baotoushashou avatar baotoushashou commented on August 17, 2024

@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.

baotoushashou avatar baotoushashou commented on August 17, 2024

Please show me your environment and procedures in details. So I could reappear your problem.

from web_socket_channel.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

@baotoushashou Would u share your code on github so that I can have a try?

from web_socket_channel.

baotoushashou avatar baotoushashou commented on August 17, 2024

@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.

baotoushashou avatar baotoushashou commented on August 17, 2024

@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.

lucasjinreal avatar lucasjinreal commented on August 17, 2024

@baotoushashou I believe it is so. I previous not notice the differences between LTE and wifi.
But problem actually exists.

from web_socket_channel.

baotoushashou avatar baotoushashou commented on August 17, 2024

@jinfagang The problem above in my real phone did not exist. Just in simulator.

from web_socket_channel.

isco-msyv avatar isco-msyv commented on August 17, 2024

Can be helpful: https://stackoverflow.com/questions/55503083/flutter-websockets-autoreconnect-how-to-implement/62095514#62095514

from web_socket_channel.

tarunjain3 avatar tarunjain3 commented on August 17, 2024

https://stackoverflow.com/a/68549605/13713269

you can refer this

from web_socket_channel.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.