flutter_nearby_connectionsによるP2P通信をiOS Simulatorのデバイス間で試してみた

2023.02.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 Delivery部の若槻です。

flutter_nearby_connectionsは、FlutterアプリでP2P(peer-to-peer)通信を可能とするプラグインパッケージです。近接しているiOSやAndroidデバイスの間でBluetoothやWi-FiによるP2P通信が可能となります。

今回は、flutter_nearby_connectionsを使用してiOS Simulatorのデバイス間でのP2P通信を試してみました。

やってみた

Flutterプロジェクト新規作成

flutter create flutter_sample_app

パッケージインストール

flutter_nearby_connectionsをインストールして追加します。

flutter pub add flutter_nearby_connections

追加できました。

pubspec.yaml

dependencies:
  flutter_nearby_connections: ^1.1.1

またその他必要なパッケージとしてdevice_info_plusおよびflutter_styled_toastをインストールします。

flutter pub add device_info_plus flutter_styled_toast

実装

Info.plistに次の通りキーを追加します。(この時VSCodeから編集する場合はXMLの記述の自動フォーマットによる型くずれに注意してください。こちらで回避策を紹介しています。)

ios/Runner/Info.plist

	<key>NSBonjourServices</key>
	<array>
		<string>_mpconn._tcp</string>
	</array>
	<key>UIRequiresPersistentWiFi</key>
	<true/>
	<key>NSBluetoothAlwaysUsageDescription</key>
	<string>flutter_nearby_connection</string>

それぞれのキーの用途はこのようになります。

次にmain.dartExampleのコードをそのまま記述しますが、古い環境向けの記述となっているため、若干の修正が必要です。

device_infoは配布停止しているので、device_info_plusを使うようにインポートする記述に置き換えます。これによりデバイスやOSの情報を取得できるようにします。

- import 'package:device_info/device_info.dart';
+ import 'package:device_info_plus/device_info_plus.dart';

device_info_plusによるデバイスモデル名の取得でタイプエラーを抑制するようにします。また通信時に利用する端末名が重複しないように、環境変数で渡した名前を末尾に付与するようにします。

+ const USERNAME = String.fromEnvironment("USERNAME");
+
    nearbyService = NearbyService();
    String devInfo = '';
    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
    if (Platform.isAndroid) {
      AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
      devInfo = androidInfo.model;
    }
    if (Platform.isIOS) {
      IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
+     devInfo = iosInfo.localizedModel!;
-     devInfo = iosInfo.localizedModel;
    }
    await nearbyService.init(
        serviceType: 'mpconn',
+       deviceName: devInfo + ' ' + String.fromEnvironment("USERNAME"),
-       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();
            }
          }
        });

ちなみに上記でStrategyとして指定したP2P_CLUSTERでは「M-to-N」通信が可能となります。P2P_STARを指定すると「1-to-N」通信、P2P_POINT_TO_POINTを指定すると「1-to-1」通信が可能となります。

動作確認

iOS Simulatorで動作確認をしてみます。

iPhoneを3台起動します。

Flutterアプリを複数台のiOS Simulatorデバイスで同時に実行する方法はこちらを参考にしてください。

flutter devicesでそれぞれのデバイスIDを確認し、flutter runでそれぞれのデバイスと任意の重複しない名前を指定しアプリを実行します。

$ flutter devices
5 connected devices:

iPhone 14 Pro (mobile)       • 303EE434-DF48-40EF-B58C-AF4B6778F1B4 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-1 (simulator)
iPhone 14 Pro Max (mobile)   • 2CA618C6-E1DF-42E2-B555-541EE8A289B3 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-1 (simulator)
iPhone 14 Pro Max 2 (mobile) • 2922EF27-FB61-4D23-B640-053CDFE46AC4 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-16-1 (simulator)
macOS (desktop)              • macos                                • darwin-arm64   • macOS 12.6 21G115 darwin-arm

$ flutter run -d 303EE434-DF48-40EF-B58C-AF4B6778F1B4 --dart-define=USERNAME=John
$ flutter run -d 2CA618C6-E1DF-42E2-B555-541EE8A289B3 --dart-define=USERNAME=Risa
$ flutter run -d 2922EF27-FB61-4D23-B640-053CDFE46AC4 --dart-define=USERNAME=Tanaka

アプリを実行できました。

そして実際にアプリを使用して3台のデバイス間でトポロジー通信をさせている様子です。

BROWSERとなっている1台の端末と、ADVERTISERの2台の端末の間で通信ができています。

注意点

flutter_nearby_connectionsはすごく簡単にP2P通信が実装できてとても楽しいパッケージですが、現在アクティブにメンテナンスされていない(最終更新は20ヶ月前)ため、本番導入する際はご注意ください。

そのため類似のパッケージを探したところflutter_blue_plusというパッケージがアクティブにメンテナンスが行われており良さそうでした。次回はこちらを試してみたいと思います。

参考

以上