使用对等技术的 Flutter 测试项目 Messager

Testproject Messager with Flutter using Peer-to-Peer Technology

我正在做一个测试项目,我想通过点对点从一个移动设备到另一个移动设备交换信息。

我的目标是制作一个聊天小部件,当您 post 一条消息时,您可以在所有连接的设备上看到它,有点像这样: 因此,如果我有一台移动设备,在我发送消息的地方,所有设备都可以看到它。

我之所以在这里寻求帮助,是因为我环顾四周,发现了 Flutter 中点对点的两个选项: A faulty example of a peer-to-peer connection in Flutter, with practically no documentation

A better-documented example of peer-to-peer connection in Flutter, which also doesn't seem to work.

根据一些人的说法,第一个选项甚至不再有效。我都试过了,但都没有达到我想要的效果。可能我100%不理解它们的区别。

有了这个我什至不知道如何编写 Dart/Flutter 代码来测试两个设备之间的连接。

我有在 Java 上使用套接字和套接字流的经验,其中一台设备将某些内容发送到套接字流中,另一台设备从套接字流中读取它,但其中一台设备是服务器,一台是客户端.

如果你能写一个简单的模型,这个点对点连接可以工作,那对我真的很有帮助。因为可用的“文档”对我一点帮助都没有。

这是我目前没有的非功能代码

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:nearby_connections/nearby_connections.dart';
import 'package:permission_handler/permission_handler.dart';

final String userName = "1";
final Strategy strategy = Strategy.P2P_CLUSTER;

class peerwidget extends StatefulWidget {
  @override
  _peerwidgetState createState() => _peerwidgetState();
}

String mytext = "";

class _peerwidgetState extends State<peerwidget> {
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: const Text("Somecrab", textDirection: TextDirection.ltr),
          actions: <Widget>[
            IconButton(
                icon: const Icon(Icons.settings),
                onPressed: () {
                  print("OPENING SETTINGS FOR BACKGROUND COLOR AND SUCH");
                }),
          ]),
      body: SingleChildScrollView(
        child: Column(children: <Widget>[
          Container(
            child: Text(mytext),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
              minimumSize: const Size(140, 50),
            ),
            onPressed: () {
              print("location");
              //setstate oderso, nächsts Bild holle
              locationpermission();
            },
            child: Column(
              // Replace with a Row for horizontal icon + text
              children: const <Widget>[
                Icon(Icons.arrow_forward),
                Text("Ask location"),
              ],
            ),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
              minimumSize: const Size(140, 50),
            ),
            onPressed: () {
              print("storage");
              //setstate oderso, nächsts Bild holle
              storagepermission();
            },
            child: Column(
              // Replace with a Row for horizontal icon + text
              children: const <Widget>[
                Icon(Icons.arrow_forward),
                Text("Ask storage"),
              ],
            ),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
              minimumSize: const Size(140, 50),
            ),
            onPressed: () {
              print("Kill all");
              //setstate oderso, nächsts Bild holle
              closeall();
            },
            child: Column(
              // Replace with a Row for horizontal icon + text
              children: const <Widget>[
                Icon(Icons.arrow_forward),
                Text("Kill all"),
              ],
            ),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
              minimumSize: const Size(140, 50),
            ),
            onPressed: () {
              print("CONNECT");
              //setstate oderso, nächsts Bild holle

              setState(() {
                connect();
              });
            },
            child: Column(
              // Replace with a Row for horizontal icon + text
              children: const <Widget>[
                Icon(Icons.arrow_forward),
                Text("CONNECT"),
              ],
            ),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
              minimumSize: const Size(140, 50),
            ),
            onPressed: () {
              print("DISCOVER");
              //setstate oderso, nächsts Bild holle
              setState(() {
                discover();
              });
            },
            child: Column(
              // Replace with a Row for horizontal icon + text
              children: const <Widget>[
                Icon(Icons.arrow_forward),
                Text("DISCOVER"),
              ],
            ),
          ),
        ]),
      ),
    );
  }
}

onConnectionInitiated() {
  mytext = "onConnectionInitiated";
}

onConnectionResult() {
  mytext = "onConnectionResult";
}

onDisconnected() {
  mytext = "onConnectionDisconnected";
}

onEndpointFound() {
  mytext = "onEndpointFound";
}

onEndpointLost() {
  mytext = "onEndpointLost";
}

connect() async {
  print("connecting started...");
  mytext = "connection started";
  try {
    await Nearby().startAdvertising(
      userName,
      strategy,
      onConnectionInitiated: (String id, ConnectionInfo info) {
        print("connection initiated!" + id + info.toString());

        onConnectionInitiated();
        // Called whenever a discoverer requests connection

        Nearby().acceptConnection(id, onPayLoadRecieved: (endpointId, payload) {
          // called whenever a payload is recieved.
        }, onPayloadTransferUpdate: (endpointId, payloadTransferUpdate) {
          // gives status of a payload
          // e.g success/failure/in_progress
          // bytes transferred and total bytes etc
        });
      },
      onConnectionResult: (String id, Status status) {
        print("connected?");
        onConnectionResult();
        // Called when connection is accepted/rejected
      },
      onDisconnected: (String id) {
        print("disconnected?");
        // Callled whenever a discoverer disconnects from advertiser
        onDisconnected();
      },
      serviceId: "com.simon.fluttershit", // uniquely identifies your app
    );
  } catch (exception) {
    print("insufficient permissions or some error!");
    // platform exceptions like unable to start bluetooth or insufficient permissions
  }
}

discover() async {
  mytext = "discovery started";
  print("Discovery started!");
  try {
    await Nearby().startDiscovery(
      userName,
      strategy,
      onEndpointFound: (String id, String userName, String serviceId) {
        print("found something: " + id + userName + serviceId);
        onEndpointFound();

        // to be called by discover whenever an endpoint is found
// callbacks are similar to those in startAdvertising method
        try {
          Nearby().requestConnection(
            userName,
            id,
            onConnectionInitiated: (id, info) {},
            onConnectionResult: (id, status) {},
            onDisconnected: (id) {},
          );
        } catch (exception) {
          // called if request was invalid
        }
      },
      serviceId: "com.simon.fluttershit",
      onEndpointLost: (String? endpointId) {
        print("was lost" + endpointId.toString());
        onEndpointLost();
      }, // uniquely identifies your app
    );
  } catch (e) {
    print("insufficient permissions or some error!" + e.toString());
    // platform exceptions like unable to start bluetooth or insufficient permissions
  }
}

void locationpermission() {
  Nearby().askLocationPermission();
}

void storagepermission() {
  Nearby().askExternalStoragePermission();
}

void closeall() {
  Nearby().stopAdvertising();
  Nearby().stopDiscovery();
}



编辑 它似乎适用于我的三星平板电脑和我的华为 mate 10 LTE,但不适用于我的华为 P40 pro!

这里有多个问题:

  1. 正如@TheFunk 友善指出的那样,并非所有权限都已授予
  2. 华为P40 Pro没有google服务,因此无法通过Peer To Peer正常通信
  3. 列表项
  4. 我之前使用的是 P2P 策略 STAR,而不是集群,现在看来可以工作了。
  5. 我对 NFC 的关注是错误的,因为设备是否具有 NFC 并不重要。
  6. 我假设两个设备都需要相同的用户名似乎是错误的。它们可以不同,只要它们声明为查找每个 EndPointId。

注意: 这个问题是两个问题之一,它们与 Flutter 的 nearby_connections 库大致相同。
对我来说,这个问题已经解决了,如果您找不到工作代码,您应该查看这个问题,我已经在其中发布了完整的连接代码,它可以工作但还没有收到包裹。 Flutter using nearby_connections in Peer to Peer to send and Receive a Package