flutter attach失败分析

最近开发中,经常出现attach失败,经过阅读源码和查阅资料,总算弄清楚了问题的原因。

第一种There are multiple observatory ports available.

➜ flutter attach
There are multiple observatory ports available.
Rerun this command with one of the following passed in as the appId:

  flutter attach --app-id com.xxx.xxx (2)
  flutter attach --app-id com.xxx.xxx

错误提示有两个app,使用 -v 看看

➜ flutter attach -v
There are multiple observatory ports available.
Rerun this command with one of the following passed in as the appId:

  flutter attach --app-id com.xxx.xxx (2)
  flutter attach --app-id com.xxx.xxx

#0      throwToolExit (package:flutter_tools/src/base/common.dart:28:3)
#1      MDnsObservatoryDiscovery.query (package:flutter_tools/src/mdns_discovery.dart:93:9)

#2      MDnsObservatoryDiscovery.getObservatoryUri (package:flutter_tools/src/mdns_discovery.dart:145:57)
#3      AttachCommand._attachToDevice (package:flutter_tools/src/commands/attach.dart:237:51)

从stack中我们发现MDnsObservatoryDiscovery中抛出了异常。mDNS是个什么东西?

第二种卡很久没有响应

Connecting to service protocol: http://127.0.0.1:63743/
[  +16 ms] Exception attempting to connect to Observatory: SocketException: OS Error: Connection refused,
errno = 61, address = 127.0.0.1, port = 56515
[   +5 ms] This was attempt #1. Will retry in 0:00:00.100000.
[ +106 ms] Exception attempting to connect to Observatory: SocketException: OS Error: Connection refused,
errno = 61, address = 127.0.0.1, port = 56516
[   +1 ms] This was attempt #2. Will retry in 0:00:00.200000.
[ +207 ms] Exception attempting to connect to Observatory: SocketException: OS Error: Connection refused,
errno = 61, address = 127.0.0.1, port = 56517
[   +1 ms] This was attempt #3. Will retry in 0:00:00.400000.

mDNS 协议 DNS-SD协议

参考 网络发现

原理

从上面的链接中可以了解到,flutter attach通过mDNS来查询调试设备的地址和端口,之后通过http进行通信。

错误分析

第一种

局域网内有两个设备注册了相同的服务,flutter attach在查询的时候发现了两个,直接抛异常

第二种

局域网内查询的时候查到了别人的服务,获取到错误的端口和authCode,导致连接不上。

解决办法

从原理中我们知道,如果能保证mDNS查询正确,那么attach就能成功。

直接指定地址

engine启动后log中会输出Observatory listening url,可以

flutter attach --debug-uri=you_observatory_listening_url

断网

从flutter 的源码中发现模拟器监听是127.0.0.1的地址,如果我们把外界的干扰断开,那就可以成功attach了,所以采取的办法就是断网

自动获取(iOS、MacOS)

每次从log复制地址还是有点麻烦,可以利用粘贴板来简化
engine启动后把url复制到粘贴板中,命令行读取粘贴板

[[UIPasteboard generalPasteboard] setURL:engine.observatoryUrl];
flutter attach --debug-uri=`pbpaste`

命令行模拟查询过程

注册

dns-sd -R com.xxx.xxx _dartobservatory._tcp local 63743 authCode=fdsafds

浏览 PTR

dns-sd -B _dartobservatory._tcp

SRV

dns-sd -L com.xxx.xxx _dartobservatory._tcp local

你可能感兴趣的:(flutter attach失败分析)