【发布时间】: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