【问题标题】:Testproject Messager with Flutter using Peer-to-Peer TechnologyTestproject Messager with Flutter 使用点对点技术
【发布时间】:2022-01-19 14:28:53
【问题描述】:

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

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

我之所以在这里寻求帮助,是因为我环顾四周,发现了 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();
}



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

【问题讨论】:

  • 你是否在你的 AndroidManifest.xml 中设置了 near_connections 包的所有权限?
  • 好的,所以现在我认为您需要在运行应用程序之前从您的 Flutter 代码中向设备请求这些权限。顺便说一句,你是如何测试这个的? Android 模拟器或 Android 设备上?我注意到 near_connections 包只支持 Android。如果您使用的是模拟器,您能否提供哪个设备/API?
  • 如果您阅读包上的文档,则需要运行时权限获取。所以基本上,在你做这些事情之前,你必须在运行时请求权限,而这段代码似乎没有这样做。阅读设置部分。 pub.dev/packages/nearby_connections
  • 尝试添加 await Nearby().askLocationAndExternalStoragePermission();在您开始发现或开始广告之前
  • 没关系,只要您在运行时请求它们并在开始发现和广告之前授予它们。在您的示例中,您的策略为空。在 pub.dev 包的示例中,他们使用 final Strategy strategy = Strategy.P2P_STAR;

标签: flutter sockets dart chat p2p


【解决方案1】:

这里有多个问题:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2015-10-13
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多