Skip to content
This repository has been archived by the owner on May 19, 2023. It is now read-only.

dynamic IP address for Meteor.connect(); #3

Open
YouSour opened this issue Jun 24, 2021 · 28 comments
Open

dynamic IP address for Meteor.connect(); #3

YouSour opened this issue Jun 24, 2021 · 28 comments

Comments

@YouSour
Copy link

YouSour commented Jun 24, 2021

hi, do you have any Example App of make dynamic ip address for meteor connection , what i'm doing right now i have text field for user input their ip address and then i store it with shared_preferences so i get it later to use with Meteor.connect(); and reconnect to meteor and i also need to listen to connection
await Meteor.connect('ws://$_ipAddress/websocket');

@wendellrocha
Copy link
Owner

Meteor.connect has to be in the main function to be able to persist throughout the life of the app. But you can try to retrieve it from preferences and pass to Meteor.connect

Ex:

  final prefs = await SharedPreferences.getInstance();
  var ip = prefs.getString('ip');
  await Meteor.connect('ws://$ip/websocket');

@YouSour
Copy link
Author

YouSour commented Jun 25, 2021

@wendellrocha i will try and test it tomorrow 😄

@YouSour
Copy link
Author

YouSour commented Jun 27, 2021

@wendellrocha i test it ready , for ip that i stored with shared_preferences it change , the problem is Meteor.connect() it don't get the ip i just changed , by the way i don't see any method how can i reconnect meteor again ( example : Meteor.reconnect(); )
here the source code i test it : https://gitlab.com/hengyousour/meteor_flutter_ver_2

@wendellrocha
Copy link
Owner

wendellrocha commented Jun 27, 2021

You can disconnect with Meteor.disconnect() and then reconnect with Meteor.reconnect() or disconnect and then connect with Meteor.connect()

If you reconnect without disconnecting first, Meteor will probably open another connection.

static void disconnect() {
_client!.close();
_notifyDisconnected();
}
/// Reconnect with the Meteor framework.
static void reconnect() {
_client!.reconnect();
}

@YouSour
Copy link
Author

YouSour commented Jun 27, 2021

@wendellrocha i did what you mention it still not work , bro , here what i did on Provider

import 'package:enhanced_meteorify/enhanced_meteorify.dart';
import 'package:flutter/foundation.dart';
import 'package:meteor_flutter_ver_2/shared_preferences/connection.dart';

class ConnectionProvider with ChangeNotifier {
  void initConnection() async {
    String? _ip = await ConnectionStorage().getIpAddress();
    print('ip $_ip');

    try {
      await Meteor.connect('ws://$_ip/websocket', enableLogs: false);
      // Do something after connection is successful
      print('connection: ${Meteor.isConnected}');
    } catch (error) {
      print(error);
      //Handle error
    }
  }

  void setIp({required String id}) {
    ConnectionStorage().setIpAddress(ip: id);
    Meteor.disconnect();
    Meteor.reconnect();
    notifyListeners();
  }
}

@wendellrocha
Copy link
Owner

Did you try calling Meteor.connect() after disconnect? From what I noticed the reconnect will call the connect with the IP of the previous connection.

@YouSour
Copy link
Author

YouSour commented Jun 27, 2021

@wendellrocha yeah, but i don't test with Meteor.connect() after disconnect yet , bro , let me test it

@YouSour
Copy link
Author

YouSour commented Jun 27, 2021

@wendellrocha the right way to listen real time connect to meteor i want to know it connect or not :
what i did it look not work the right way:

class ConnectionProvider with ChangeNotifier {
  bool _isConnected = false;
  bool get isConnected => _isConnected;

  void initConnection() async {
    String? _ip = await ConnectionStorage().getIpAddress();
    print('ip $_ip');

    try {
      await Meteor.connect('ws://$_ip/websocket', enableLogs: false);
      // Do something after connection is successful
      // print('connection: ${Meteor.isConnected}');
    } catch (error) {
      print(error);
      //Handle error
    }

    // listen real time connection meteor with flutter
    Meteor.connectionListener = (ConnectionStatus connectionStatus) {
      if (describeEnum(connectionStatus) == "CONNECTED") {
        _isConnected = true;
      } else {
        _isConnected = false;
      }
    };

    notifyListeners();
  }

  void setIp({required String id}) async {
    ConnectionStorage().setIpAddress(ip: id);
    Meteor.disconnect();
    initConnection();
    notifyListeners();
  }
}

@wendellrocha
Copy link
Owner

@YouSour Using ConnectionListener is the fastest way to receive notifications from the connection.

I have no experience with Provider, so I did a quick example in "pure" Flutter and the connection worked. I hope it helps you with something.

Code
import 'package:enhanced_meteorify/enhanced_meteorify.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() async {
  try {
    WidgetsFlutterBinding.ensureInitialized();
    final ip = await PrefsService.getString('ip');
    ConnectionService connection = ConnectionService();
    if (ip.isNotEmpty) {
      connection.setIP(ip);
      final status = await connection.connect();
      print(status);
    }
    runApp(MyApp());
  } on MeteorError catch (error) {
    print(error.message);
  }
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final _controller = TextEditingController();

  void _connect() {
    if (_controller.text.isNotEmpty) {
      PrefsService.setString('ip', _controller.text);
      ConnectionService conn = ConnectionService();
      conn.setIP(_controller.text);
      conn.connect();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextFormField(controller: _controller),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _connect(),
        tooltip: 'Cpnnect',
        child: Icon(Icons.settings_ethernet),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class PrefsService {
  static void setString(String key, String item) async {
    final prefs = await SharedPreferences.getInstance();
    prefs.setString(key, item);
  }

  static Future<String> getString(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(key) ?? '';
  }
}

class ConnectionService {
  late String _ip;

  void setIP(String ip) => this._ip = ip;
  String get ip => this._ip;

  bool get isConnected => Meteor.isConnected;

  Future<ConnectionStatus> connect() async {
    if (isConnected) disconnect();
    return await Meteor.connect('ws://${this._ip}/websocket');
  }

  void disconnect() {
    Meteor.disconnect();
  }
}

@YouSour
Copy link
Author

YouSour commented Jun 27, 2021

@YouSour i ' ll check and work on it with your quick example tomorrow , it midnight here , i will confirm you , if i have a problem 🙂

@YouSour
Copy link
Author

YouSour commented Jun 28, 2021

@wendellrocha i test your example code , if i want to use Meteor.connectionListener where should i put that line ? because i need to check if connection is connected i show login page to user and if connection is disconnect i show connect page to user

@wendellrocha
Copy link
Owner

I can't think of a "right place" to use listener. You can put it somewhere in your project where you can listen for connection changes and make decisions about what to display to the user.

@YouSour
Copy link
Author

YouSour commented Jun 29, 2021

@wendellrocha dynamic ip it works now , but Meteor.connectionListener look like it isn't listen when i stop meteor project and then i run meteor project again Meteor.connectionListener keep disconnected

@wendellrocha
Copy link
Owner

Meteor.connectionListener only notified that it was connected after login. Now it notifies you as soon as it successfully connects to Meteor. Can you test before publishing a new version?

dependencies:
  enhanced_meteorify:
    git: 
       url: git://github.com:wendellrocha/enhanced_meteorify.git

@YouSour
Copy link
Author

YouSour commented Jun 29, 2021

@wendellrocha i test it , Meteor.connectionListener it can listen after i stop meteor project and run again , but it connected and then it disconnect again

@YouSour
Copy link
Author

YouSour commented Jun 29, 2021

@wendellrocha
Copy link
Owner

The listener did the right thing. Noticed disconnection after DDP disconnected by an error.

@YouSour
Copy link
Author

YouSour commented Jul 7, 2021

@wendellrocha sorry , i was a bit busy , i try to test it again and again and i also test your example code it get that error too , i noted every time i set a new ip address to Meteor.connect(); i got this error :

flutter: \^[[31m[DDP] :: Disconnect due to websocket onError<…>
flutter: \^[[31m[DDP] :: Error: WebSocketChannelException: WebSocketChannelException: SocketException: Connection failed (OS Error: No route to host, errno = 65), address = 23, port = 80<…>
flutter: \^[[31m[DDP] :: Schedule reconnect due to websocket onError<…>

and then it disconnect , i think a new ip address that i just input it doesn't replace on Meteor.connect() , what is the main problem ? 🤔

@wendellrocha
Copy link
Owner

No route to host. The device cannot find the server. Check the server IP.

@YouSour
Copy link
Author

YouSour commented Jul 7, 2021

@wendellrocha did you test your example code that you give me ? it doesn't work too , is it work for you or not ?

@wendellrocha
Copy link
Owner

Yep.
image

@YouSour
Copy link
Author

YouSour commented Jul 7, 2021

@wendellrocha can you test like this , first you put a wrong ip address then input the right one again , it work or not ?
second: don't use 10.0.2.2:3000 use kind of this example : 192.168.1.15:3000
third : please use with Meteor.connectionListener check if connection is connected or not and print it out ? i'm not sure it can be Meteor.connectionListener or not ?

@wendellrocha
Copy link
Owner

wendellrocha commented Jul 7, 2021

Also note that the address 127.0.0.1 on your development machine corresponds to the emulator's own loopback interface. If you want to access services running on your development machine loopback interface (a.k.a. 127.0.0.1 on your machine), you should use the special address 10.0.2.2 instead.

I forked the package because I needed to make some adjustments to the project I was working on. I'm no longer on this project. So, let's take it easy on the demands, I move this package when I have the time and patience.

@YouSour
Copy link
Author

YouSour commented Jul 7, 2021

@wendellrocha ok

@YouSour
Copy link
Author

YouSour commented Jul 8, 2021

@wendellrocha it look like something wrong with Meteor.connectionListener , pls check it

@github-actions
Copy link

github-actions bot commented Sep 7, 2021

Stale issue message

@YouSour
Copy link
Author

YouSour commented Sep 11, 2021

@wendellrocha any news ?

@github-actions
Copy link

Stale issue message

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants