ksenia312 / nearby_service

Nearby Service Flutter Plugin for creating connections in a P2P network.
https://pub.dev/packages/nearby_service
BSD 3-Clause "New" or "Revised" License
47 stars 5 forks source link

[QUESTION]: Not finding devices #16

Open aramikg opened 1 month ago

aramikg commented 1 month ago

Question:

So I have the key in my info.plist for iOS, I'm setting isBrowser, I've asked for the permissions, and my devices are still not finding each other. One Device logs that it is advertised while the other logs that it's browsing but the list of devices keep coming back empty. Am I missing anything?

Code Snippet:

Provide any relevant code snippets where you are using the API

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:nearby_service/nearby_service.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';

class NearbyServiceProvider with ChangeNotifier {
  final NearbyService _nearbyService =
      NearbyService.getInstance(logLevel: NearbyServiceLogLevel.debug);
  final StreamController<String> _fileReceivedController = StreamController<String>.broadcast();

  Stream<String> get fileReceivedStream => _fileReceivedController.stream;
  NearbyDevice? connectedDevice; // Store the connected device

  bool isInitialized = false;
  bool isConnected = false;

  Stream<List<NearbyDevice>> get peersStream => _nearbyService.getPeersStream();

  Future<void> initializeService(bool isBrowser) async {
    if (isInitialized) return;
    await _nearbyService.initialize(
      data: NearbyInitializeData(
        iosDeviceName: 'My Device ${isBrowser ? 'Browser' : 'Advertiser'}',
      ),
    );

    if (isBrowser) {
      _nearbyService.ios?.setIsBrowser(value: true);
      print('::: starting browsing for peers');
      await _browseForPeers();
    } else {
      _nearbyService.ios?.setIsBrowser(value: false);
      print('::: starting discovering peers');
      await _startDiscovering();
    }

    isInitialized = true;
    notifyListeners();
  }

  Future<void> _browseForPeers() async {
    final result = await _nearbyService.discover();
    if (!result) {
      print('::: failed to start browsing');
      return;
    }
    _nearbyService.getPeersStream().listen((peers) {
      debugPrint('::: Discovered peers!: ${peers}');
      debugPrint("Discovered peers: ${peers.map((peer) => peer.info.id).join(", ")}");
    });

    _nearbyService.getCommunicationChannelStateStream().listen((state) {
      if (state == CommunicationChannelState.connected && connectedDevice != null) {
        print('::: connected to ${connectedDevice!.info.id}');
        isConnected = true;
        _setupCommunicationChannel(connectedDevice!); // Pass connected device
      }
    });
  }

  Future<void> _startDiscovering() async {
    final result = await _nearbyService.discover();
    if (!result) {
      print('::: failed to start discovering');
      return;
    }
    _nearbyService.getPeersStream().listen((peers) {
      debugPrint("Discovered peers -: ${peers.map((peer) => peer.info.id).join(", ")}");
    });
  }

  Future<void> connectToPeer(NearbyDevice device) async {
    final result = await _nearbyService.connectById(device.info.id);
    if (result) {
      connectedDevice = device;
    }
  }

  void _setupCommunicationChannel(NearbyDevice device) {
    _nearbyService.startCommunicationChannel(
      NearbyCommunicationChannelData(
        device.info.id,
        filesListener: NearbyServiceFilesListener(
          onData: (filesPack) async {
            final directory = await getApplicationDocumentsDirectory();
            final fileName = basename(filesPack.files[0].path);
            final filePath = '${directory.path}/$fileName';
            final file = File(filePath);
            await file.writeAsBytes(await File(filesPack.files[0].path).readAsBytes());

            _fileReceivedController.add(filePath);
          },
        ),
        messagesListener: NearbyServiceMessagesListener(
          onData: (message) {
            // Handle messages here
          },
        ),
      ),
    );
  }

  void sendFile(File file) {
    if (!isConnected) {
      print('::: not connected to any device');
      return;
    }
    final fileInfo = NearbyFileInfo(path: file.path);
    // Create a NearbyMessageFilesRequest to wrap the file
    final messageFilesRequest = NearbyMessageFilesRequest.create(
      files: [fileInfo], // Pass the list of files you want to send
    );

    // Send the file along with a message
    _nearbyService.send(
      OutgoingNearbyMessage(content: messageFilesRequest, receiver: connectedDevice!.info),
    );
  }

  @override
  void dispose() {
    _fileReceivedController.close();
    _nearbyService.stopDiscovery();
    super.dispose();
  }
}

Your effort is appreciated 💗

Princewil commented 1 month ago

Yeah. Noticed it too.

In my case it sometimes find devices other times it doesn't. Although it seems only the Browser device can find devices, the advertised device can't find other devices.

aramikg commented 1 month ago

Yea, I have been trying to debug to see why for about 3 days now, not once has my browser found other devices... Thanks for the info.

ksenia312 commented 1 month ago

Although it seems only the Browser device can find devices, the advertised device can't find other devices.

@aramikg this comment is correct, you can read more here https://github.com/ksenia312/nearby_service/issues/15#issuecomment-2408689707

ksenia312 commented 1 month ago

@aramikg Hello, I see your question and I'm investigating to find a solution

I will return with answer as soon as I found

aramikg commented 1 month ago

Thanks, yes I understand that the advertiser doesn't see the browser at first but again my case is the browser doesn't see the advertiser, I have tried multiple devices.

ksenia312 commented 1 month ago

@aramikg Yes, I got the problem and I'm able to reproduce with your code I need more time to find what exactly goes wrong there

Very thanks for your effort and time, I'll try to find a solution as soon as possible!

ksenia312 commented 1 month ago

@aramikg Hello, I found the problem! Your code definitely should work, the bug is inside my source code.

The call

 _nearbyService.ios?.setIsBrowser(value: value);

is void but in real life I use StreamController inside and listener to it, so it takes some time to update isBrowser value (under the hood of nearby service) after calling setIsBrowser().

I apologise for this and I will update the plugin with fix

Until the update, you can try to call await Future.delayed()here:

   if (isBrowser) {
      nearbyService.ios?.setIsBrowser(value: true);
      await Future.delayed(const Duration(milliseconds: 100));
      print('::: starting browsing for peers');
      await _browseForPeers();
    } else {
      nearbyService.ios?.setIsBrowser(value: false);
      await Future.delayed(const Duration(milliseconds: 100));
      print('::: starting discovering peers');
      await _startDiscovering();
    }

For me this fix is working

I'll update the plugin as soon as possible! Thanks for letting me know about the problem

ksenia312 commented 1 month ago

@aramikg new version nearby_service 0.1.1 is available to test

If everything is okay now, we can close the issue