becvert / cordova-plugin-zeroconf

Cordova ZeroConf Plugin
MIT License
81 stars 57 forks source link

[Android] Nothing happens when wifi is enabled, Error when wifi is disabled #46

Closed Dipayon3D closed 5 years ago

Dipayon3D commented 6 years ago

I am using this plugin along with cordova-plugin-websocket-server to make a multiplayer Android game. The server plugin is working fine, but the zeroconf plugin is not working . Nothing happens when I publish a service, no Success or Failure callback is fired . . . Same for "watch(type, domain, success, failure)", nothing happens .

Dipayon3D commented 6 years ago

for the watch(), when wifi is disabled it gives me error. But when wifi is enabled it gives me nothing . . . ! Please help.

becvert commented 6 years ago

OK I'll review that later on. In the meantime check in your code that wifi is on before calling the plugin. You could ask the players to turn their wifi on too because using this plugin and websocket-server does not make much sense without wifi to me.

Dipayon3D commented 6 years ago

Yeah, I'm turning the wifi on . . . Gives me nothing . . . That's the problem. It should fire either the success or failure callback . . . Take a look into it please . . . Thank you for your efforts.

emcniece commented 6 years ago

@Dipayon3D can you share any code?

Dipayon3D commented 6 years ago

sure . . .

here's the server side and client side code . . .

var SERVICE_TYPE = '_my-service._tcp.', // '_http._tcp.'
    HOST_NAME = 'my host';

function startServer(){

  // Specify 0 as the port number, so that a random free port is used
  if(!wsserver){
     alert("No WebSocket !");
     return;
  }

  if(!zeroconf){
     alert("No Zeroconf !");
     return;
  }

  wsserver.start(0, {

      'onFailure' :  function(addr, port, reason) {
          navigator.notification.alert(
              'Stopped listening on '+addr+' : '+port+'. Reason: '+reason,  // message
              function(){},         // callback
              'Stopped',            // title
              'GOT IT . . .'                  // buttonName
          );
      },

      // WebSocket Connection handlers
    'onOpen' : function(conn) {
        /* conn: {
         'uuid' : '8e176b14-a1af-70a7-3e3d-8b341977a16e',
         'remoteAddr' : '192.168.1.10',
         'acceptedProtocol' : 'my-protocol-v1',
         'httpFields' : {...},
         'resource' : '/?param1=value1&param2=value2'
         } */

        navigator.notification.alert(
            'A user connected from '+conn.remoteAddr,  // message
            function(){},         // callback
            'Connected',            // title
            'GOT IT . . .'                  // buttonName
        );
    },

    'onMessage' : function(conn, msg) {

        navigator.notification.alert(
            conn+" , "+msg,  // message
            function(){},         // callback
            'Message',            // title
            'GOT IT . . .'                  // buttonName
        );

    },

    'onClose' : function(conn, code, reason, wasClean) {

        navigator.notification.alert(
            "A user disconnected from "+conn.remoteAddr+", with Code - "+code+", because of "+reason+", Clean Connection : "+wasClean,  // message
            function(){},         // callback
            'Connected',            // title
            'GOT IT . . .'                  // buttonName
        );

    },
    // Other options
    'origins' : [ 'file://' ], // validates the 'Origin' HTTP Header. // [ 'file://',"http://","*" ]
    'protocols' : [ 'my-protocol-v1', 'my-protocol-v2' ], // validates the 'Sec-WebSocket-Protocol' HTTP Header.
    'tcpNoDelay' : true // disables Nagle's algorithm.

  },

  function onStart(addr, port){

      // window.plugins.spinnerDialog.show("GetInterfaces() Called", "Please wait...", function(){});

      var ip_addresses;

      // Check whether we are listening on IPv4 or IPv6

      if(/^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$/.test(addr)){
          ip_addresses = 'ipv4Addresses';
      } else {
          ip_addresses = 'ipv6Addresses';
      }

      // Call getInterfaces in order to know the IP addresses of each network _interface

      wsserver.getInterfaces(function(result){

          // window.plugins.spinnerDialog.hide();

          /*
           {"p2p0":{"ipv4Addresses":[],"ipv6Addresses":["fe80::bcd1:d3ff:fe51:ea60%p2p0"]}}
          */

          // if(result){
          //    if(result.p2p0.ipv4Addresses[0]){
          //       alert("IPV4Addresses - "+ result.p2p0.ipv4Addresses[0]);
          //    }else{
          //       alert("IPV6Addresses - "+ result.p2p0.ipv6Addresses[0]);
          //    }
          // }

          zeroconf.register(SERVICE_TYPE, 'local.', HOST_NAME, port, {

              // Publish the correct IP address on the TXT record
              server_ip: ( result.p2p0.ipv4Addresses[0] ) ? result.p2p0.ipv4Addresses[0] : result.p2p0.ipv6Addresses[0]

          }, function(data){
              // Here we have successfully advertised the service

              // window.plugins.spinnerDialog.hide();

              alert('Service Advertised - '+ data);

          }, function(cause){
             // Failed to advertised
            //  window.plugins.spinnerDialog.hide();
             alert('Failed to advertise Service - '+ cause);
          });

      }, function(error){

        //  window.plugins.spinnerDialog.hide();
         alert('GetInterfaces Error - '+ error);

      });

  },

  function onDidNotStart(reason) {

    alert('Reason for not starting '+ reason);

  });

}

var connection;

function watchForServer(){

  if(!zeroconf){
    alert("No Zeroconf !");
    return;
  }

  window.plugins.spinnerDialog.show("Looking For Service", "Please wait...", function(){});

  zeroconf.watch(SERVICE_TYPE, 'local.', function(result){

      window.plugins.spinnerDialog.hide();

      var service = result.service, hostname, url;

      alert("Watch Result ServerIP - "+ service.txtRecord.server_ip);

      if (result.action === 'added') {

          hostname = service.txtRecord.server_ip;

          if(/^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$/.test(hostname)){
              url = ['ws://', hostname, ':', service.port, '/'].join(''); // ipv4
          } else {
              url = ['ws://[', hostname, ']:', service.port, '/'].join(''); // ipv6 // hostname.slice(0, hostname.length - 5)
          }

          connection = new WebSocket(url);
          connection.onopen = function() {
              // Now the client is connected
              alert("Now the client is connected "+ result.service);
          }
      } else if (result.action == 'resolved') {
          alert("service resolved "+ result.service);
      }else{
          alert("Service Removed "+ result.service);
      }
  }, function(cause){
    // failed to watch for service
    window.plugins.spinnerDialog.hide();
    alert("Failed to watch "+ cause);
  });

}
emcniece commented 6 years ago

@Dipayon3D thank you for sharing. A few questions:

  1. How are you setting zeroconf? Usually this is cordova.plugins.zeroconf unless using Ionic-Native. Your syntax for zeroconf.register and zeroconf.watch looks correct.
  2. Do you get any results for var SERVICE_TYPE = '_http._tcp.' ?
  3. What happens if you run cordova.plugins.zeroconf.watch('_http._tcp.', 'local.', console.log, console.err); in your browser devtools while your app is running?
  4. Do you see your services using some version of Bonjour Browser? OSX, Windows
Dipayon3D commented 6 years ago

I'm setting everything in the recommended way . . . And SERVICE_TYPE = '_my-service._tcp.' works fine and SERVICE_TYPE = '_http._tcp.' as well . . .

Actually I'm trying to use it for an Android multiplayer game . . . So I've tested it on various Android devices . . . The server runs successfully , but when the other device starts to watch for services, nothing happens . . . It just keeps checking forever . . . No error or result . . .

I'm programmatically turning the wifi ON using another plugin at the startup . . . I have no earthly idea where to go from here with these plugins . . .

emcniece commented 6 years ago

I'm curious if you are experiencing the same problem that I have been fighting with: changing Wifi networks after the Zeroconf plugin has been initialized (when the app starts up) breaks the mDNS scanning.

I added a reInit() method recently to help with this, but it hasn't been fully released yet.

Can you run your app again, but make sure that the phone is on the correct Wifi network before opening the app? We need to see if you get results when the app starts and doesn't change networks.

Dipayon3D commented 6 years ago

Yeah, I've tried that too . . . the same result unfortunately . . . Are you having trouble using these plugins as well??

emcniece commented 6 years ago

Yes, but my problems are lower in the OS layer where Android decides to route browser-based traffic through WiFi or GSM based on which interface has an internet connection.

This plugin works well for me in normal circumstances... it's only when I change the source of the internet that it behaves poorly, and that is not not something this plugin can control.

Do you have different results if you disable your phone's cell network data connections?

becvert commented 6 years ago

just to be sure, is zeroconf.register called at all? can you confirm that you are getting an alert in any of its callbacks? if successfull, as @emcniece said, can you see your services with another zeroconf app? (Bonjour Browser or Service Browser in Google Play for instance)

Dipayon3D commented 6 years ago

@emcniece the result is same with the cell network data connection . . . @becvert yes, zeroconf.register(...) is being called . . . I get the success callback firing . . . I'm afraid it's the zeroconf.watch(...) , that's not doing anything . . . Did I miss anything ?? Here's the watch method below -

var connection;

function watchForServer(){

  if(!zeroconf){
    alert("No Zeroconf !");
    return;
  }

  window.plugins.spinnerDialog.show("Looking For Service", "Please wait...", function(){});

  zeroconf.watch(SERVICE_TYPE, 'local.', function(result){

      window.plugins.spinnerDialog.hide();

      var service = result.service, hostname, url;

      alert("Watch Result ServerIP - "+ service.txtRecord.server_ip);

      if (result.action === 'added') {

          hostname = service.txtRecord.server_ip;

          if(/^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$/.test(hostname)){
              url = ['ws://', hostname, ':', service.port, '/'].join(''); // ipv4
          } else {
              url = ['ws://[', hostname, ']:', service.port, '/'].join(''); // ipv6 // hostname.slice(0, hostname.length - 5)
          }

          connection = new WebSocket(url);
          connection.onopen = function() {
              // Now the client is connected
              alert("Now the client is connected "+ result.service);
          }
      } else if (result.action == 'resolved') {
          alert("service resolved "+ result.service);
      }else{
          alert("Service Removed "+ result.service);
      }
  }, function(cause){
    // failed to watch for service
    window.plugins.spinnerDialog.hide();
    alert("Failed to watch "+ cause);
  });

}
becvert commented 6 years ago

If I were you, again as @emcniece said, I would just console.log(result) or alert(result) in watch

Dipayon3D commented 6 years ago

I did . . . It's in the code I provided . . . But somehow neither the success nor failure callback is firing !! Does the implementation looks good to you (in the code provided) ??

becvert commented 6 years ago

are you sure service.txtRecord is not null for instance? I'm just trying to go step by step here. otherwise I can't see anything wrong. again use a bonjour browser app to check that the service is registered.

Dipayon3D commented 6 years ago

Ok . . . I'll do some more experimenting and let you know . . . Than you for your supports :)

becvert commented 6 years ago

are you using the hotspot mode or WI-FI direct?

Dipayon3D commented 6 years ago

I'm just turning the wifi on using another plugin . . . not creating any hotspot . . . Do I need hotspot ??

becvert commented 6 years ago

no. It's just that in your code you're looking for the p2p0 interface which is Wifi Direct I think. Hotspot mode and wifi direct are either not well supported or not tested for this plugin. Can you confirm that your devices are all connected to the same router?

Dipayon3D commented 6 years ago

No, devices are not connected to same router . . . I used p2p0 because in my server code, inside wsserver.getInterfaces(function(result){....}) I used alert(JSON.stringify(result)); and it gave me the following response after the server started - {"p2p0":{"ipv4Addresses":[],"ipv6Addresses":["fe80::bcd1:d3ff:fe51:ea60%p2p0"]}} so I had to use response.p2p0 . . .

becvert commented 6 years ago

ok I think that's the source of your problem. your devices must be on the same router. which wifi plugin are you using?

Dipayon3D commented 6 years ago

I've used cordova-plugin-wifi just to enable the wifi on dviceready . . .

becvert commented 6 years ago

ok. I don't know how you're setup but try to connect your devices to the same router. otherwise if in hotspot mode or wifi direct try also to disable mobile data. good luck.

becvert commented 5 years ago

Closing old issue. Feel free to reopen.