The Documentation to this Library is extremely lacking and it's very hard to understand what the example does.
Could you please go through your example and add with // comments, what each code block exactly does?
It would make it a lot easier to understand and implement at other places.
https://pub.dev/packages/flutter_nearby_connections/example
This fix would take roughly 10 minutes, as you are the one who already understands the code and know what each line does.
Eventually, if I have enough time and energy to look at it, I may be able to make a some sort of documentation.
This is my impression of the code:
At the beginning the devices decide, whether they are a browser (searcher)
or an advertiser.
the browser will find other advertisers on the list,
which the advertiser only waits until he gets connected.
Then both can send messages to each other, once the connection has been established.
Initializing & Settings
Here are all Settings declared, which are meant required for a
successfull Peer-to-Peer connection.
For Example we choose here the strategy, which is P2P_Cluster.
Once this action nearbyService is called,
it checks if the devicetype is browser.
Presumably this doesn't actually check IF the Device this program is used
on IS a Browser, but much rather if the device is currently
advertising or browsing / looking for other devices.
Either way it then stops searching for peers (other devices),
waits 200 microseconds, which is aproximately 0.002 seconds, until it starts browsing for peers again.
If the device turns out to be a "advertiser"
it stops advertising peers and stops browsing,
then waits 0.002 seconds until it starts
advertising peers and starts browsing.
await nearbyService.init(
serviceType: 'mpconn',
deviceName: devInfo,
strategy: Strategy.P2P_CLUSTER,
callback: (isRunning) async {
if (isRunning) {
if (widget.deviceType == DeviceType.browser) {
await nearbyService.stopBrowsingForPeers();
await Future.delayed(Duration(microseconds: 200));
await nearbyService.startBrowsingForPeers();
} else {
await nearbyService.stopAdvertisingPeer();
await nearbyService.stopBrowsingForPeers();
await Future.delayed(Duration(microseconds: 200));
await nearbyService.startAdvertisingPeer();
await nearbyService.startBrowsingForPeers();
}
}
});
Declarations
enum DeviceType { advertiser, browser }
class DevicesListScreen extends StatefulWidget {
const DevicesListScreen({required this.deviceType});
final DeviceType deviceType;
class _DevicesListScreenState extends State<DevicesListScreen> {
List<Device> devices = [];
List<Device> connectedDevices = [];
late NearbyService nearbyService;
late StreamSubscription subscription;
late StreamSubscription receivedDataSubscription;
Check for Android or IOS
nearbyService = NearbyService();
String devInfo = '';
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
//If this is android then this will be executed
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
devInfo = androidInfo.model!;
}
//If this is run on IOS, then this will be executed
if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
devInfo = iosInfo.localizedModel!;
}
Start & End Connection
_onButtonClicked(Device device) {
switch (device.state) {
case SessionState.notConnected:
nearbyService.invitePeer(
deviceID: device.deviceId,
deviceName: device.deviceName,
);
break;
//If connected make a disconnection
case SessionState.connected:
nearbyService.disconnectPeer(deviceID: device.deviceId);
break;
//If it's during a connection ignore it
case SessionState.connecting:
break;
}
}
Subscription
If the subscriptionstate, aka the status of the connection between each other has changed, it wil print all elements of devices it has found and their state. (Basically if they're already connected or not.)
If this is run on an android device and the device is currently connected,
the searching for peers stops. Else if it's not connected the searching for peers starts.
subscription =
nearbyService.stateChangedSubscription(callback: (devicesList) {
devicesList.forEach((element) {
print(
" deviceId: ${element.deviceId} | deviceName: ${element.deviceName} | state: ${element.state}");
if (Platform.isAndroid) {
if (element.state == SessionState.connected) {
nearbyService.stopBrowsingForPeers();
} else {
nearbyService.startBrowsingForPeers();
}
}
});
setState(() {
devices.clear();
devices.addAll(devicesList);
connectedDevices.clear();
connectedDevices.addAll(devicesList
.where((d) => d.state == SessionState.connected)
.toList());
});
});
Send Data
nearbyService.sendMessage(
device.deviceId, myController.text);
myController.text = '';
Received Data
receivedDataSubscription =
nearbyService.dataReceivedSubscription(callback: (data) {
print("dataReceivedSubscription: ${jsonEncode(data)}");
showToast(jsonEncode(data),
context: context,
axis: Axis.horizontal,
alignment: Alignment.center,
position: StyledToastPosition.bottom);
});
End search
void dispose() {
subscription.cancel();
receivedDataSubscription.cancel();
nearbyService.stopBrowsingForPeers();
nearbyService.stopAdvertisingPeer();
super.dispose();
}
But it's still not clear what exactly.
Your code works great, but it's a mystery how it works.
Thanks.