STF stf 连接各操作系统上安卓设备的操作方法分享

陈恒捷 · 2016年12月30日 · 最后由 mrbao 回复于 2019年12月19日 · 229 次阅读
本帖已被设为精华帖!

前言

stf 作为多设备管理平台,对于设备的接入支持也是十分灵活的。最近尝试了使用 stf 在 Ubuntu 、mac 及 windows 下进行设备的连接,发现原来全都可以支持,因此上来分享一下。

原理简析

先来看下官方在部署文档给出的后端组件架构图

有两个我们看得见的组件在这里没有画出来。在顶部 websocket 再上面应该就是网页端(stf-app),在底部 provider 再下面就是 adb 。stf-provider 通过 adbkit 这个组件和 adb server 进行连接。不清楚 adb server 是什么的同学建议看下 ADB 源码分析(一) ,虽然比较旧,但讲得比较清晰。

stf 各组件间都是通过网络进行通讯的,其中所有和设备的连接最终都会集中到 provider 。所以我们只需要在 provider 及它以下的层级做文章就好了。

先来看一下 provider 的参数:

stf provider --help

  Usage: provider [options] [serial...]

  start provider

  Options:

    -h, --help                         output usage information
    -s, --connect-sub <endpoint>       sub endpoint
    -p, --connect-push <endpoint>      push endpoint
    -n, --name <name>                  name (or os.hostname())
    --min-port <port>                  minimum port number for worker use
    --max-port <port>                  maximum port number for worker use
    --public-ip <ip>                   public ip for global access
    -t, --group-timeout <seconds>      group timeout
    -r, --storage-url <url>            URL to storage client
    --heartbeat-interval <ms>          heartbeat interval
    --adb-host <host>                  ADB host (defaults to 127.0.0.1)
    --adb-port <port>                  ADB port (defaults to 5037)
    -R, --allow-remote                 Whether to allow remote devices to be set up
    --screen-ws-url-pattern <pattern>  screen WebSocket URL pattern
    --connect-url-pat%
  • 上层连接

对于上层连接,我们需要指定 --connect-sub--connect-push 这两个参数,这两个参数的值需要对应 triproxy dev 中的 --bind-pub--bind-pull 的参数。

举个例子:

# 假设在  ip 地址为 192.168.1.2 的机器上使用以下参数启动 triproxy dev
$ stf triproxy dev  --bind-pub "tcp://*:7250"  --bind-dealer "tcp://*:7260" --bind-pull "tcp://*:7270"

# provider 应使用的对应参数(为了简化,这里只写了这两个参数,实际不止)
$ stf provider --connect-sub tcp://192.168.1.2:7250  --connect-push tcp://192.168.1.2:7270

除此之外,provider 还有一个必须指定的参数 --storage-url 。直接把启动 stf storage-temp 的机器的 ip 地址填进去就可以了(前提是 nginx 有配置好反向代理,把 /s/ 路径映射到 storage-temp 这个组件对应的端口)。详细配置方式建议参考 STF 开发环境搭建与制作 docker 镜像过程

  • 下层连接

下层连接我这里指的就是和 adb server 的连接了,只有两个参数:--adb-host--adb-port。使用默认值的话会连接 provider 所在机器的 adb server 。

在可以装上 stf 的操作系统上(Linux,Mac),直接启动新的 stf provider 就可以了,结构比较简单,而且也没太大必要配置这两个参数。

但在 windows 上,由于 stf 不支持 windows ,所以只能通过配置 adb host 的方式来让其它机器的 provider 连接 windows 上启动的 adb server 。

举例:

windows 上启动 adb server 并对外暴露 5037 端口

adb -a -P 5037 fork-server server

其他支持 stf 的操作系统上连接 windows 上的 adb server(架设 windows 设备的 ip 地址是 192.168.1.3)

# 此处为了简化,只写了 --adb-host 参数的值
$ stf provider --adb-host 192.168.1.3 

具体操作

假设有三台机器:

  • 192.168.1.2:Linux 主机,部署并启动了 stf 全部组件,装有 android sdk
  • 192.168.1.3: Windows 主机,装有 android sdk
  • 192.168.1.4:Mac 主机,安装了 stf

1、通过配置 adb host 的方式连上 windows 主机上的设备:

在 Windows 主机上启动 adb server 并对外暴露端口

adb -a -P 5037 fork-server server

在 Linux 主机上启动对应的 stf provider

$ stf provider --name "provider-windows_3" --connect-sub tcp://192.168.1.2:7250  --connect-push tcp://192.168.1.2:7270  --storage-url http://192.168.1.2  --public-ip 192.168.1.2 --min-port=30001  --max-port=35000  --heartbeat-interval 20000 --adb-host 192.168.1.3

2、通过配置新的 provider 连上 Mac 主机上的设备:

在 Mac 主机上启动 stf provider

$ stf provider --name "provider-mac_4" --connect-sub tcp://192.168.1.2:7250  --connect-push tcp://192.168.1.2:7270  --storage-url http://192.168.1.2  --public-ip 192.168.1.2 --min-port=35000  --max-port=40000  --heartbeat-interval 20000

这里写得比较简单。若对于具体实操仍有疑问,可以查看 [STF 手机设备管理平台] 连接其它操作系统上的安卓设备实操介绍 : https://testerhome.com/topics/7966

缺点

由于 provider 只是与 adb 通讯,没有启动 adb server 的权限,因此采用 adb host 方式时若 adb server 挂了,provider 也会跟着挂(连接不到 adb server 的异常不会被捕获)。相当于 windows 重启后,其它机器上对应的 provider 进程也必须手动重启。

所以除了 windows 非不得已需要使用这样方式,其它时候十分不推荐采用这种方式,一般很难联想到启动一个服务后还得重启另一台设备上的服务。




===================提问分割线====================

好吧,上面说了这么多,主要是为了吸引一些使用 stf 的同学过来。。。有问题想咨询大家。

现在我司采购了一批 奥睿科(ORICO)A3H4、A3H7 和 A3H10 的 USB hub ,里面使用的是 VIA VL812 芯片,准备给 stf 连接收集用。但实际使用中,发现它和 Ubuntu 上的 adb server 存在兼容性问题,平均每隔 20 分钟 adb 就会自动断线重连一次(但 Ubuntu 的 USB 设备相关信息都显示断线期间设备还是正常连接的)。但在 Mac 和 Windows 上就没问题。

所以想借此机会收集下大家目前使用的 USB Hub 型号以及稳定性。

收集方式很简单,大家把下面的内容保存到一个 .sh 文件,其中 dcee06f138b7 替换成自己设备的序列号(显示在 adb devices 中的那个),然后在命令行启动。过一个晚上后把输出结果、操作系统版本及 USB Hub 型号发在回帖中即可。

#!/usr/bin/env bash
DEVICE_SERIAL="dcee06f138b7"

echo "Begin to monitor adb connection of device" $DEVICE_SERIAL "in" `date '+%Y-%m-%d %H:%M:%S'`
for i in {1..3}
do
  echo "The" $i "time"
  adb -s $DEVICE_SERIAL logcat > /dev/null 2>&1
  echo "Disconnectd time:" `date '+%Y-%m-%d %H:%M:%S'`

  # sleep 20s for auto reconnection
  sleep 20
done

# like pause in windows bat
read -rsp $'Press any key to continue...\n' -n 1 key

感谢大家~

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 70 条回复 时间 点赞
思寒_seveniruby 将本帖设为了精华贴 12月30日 05:30

加精理由: 对 stf 的架构分析的很深入

感谢分享干货

之前采购 hub 的时候看到的,哈哈英语不好,我的理解是尽量使用 usb2.0 设备。另外要带外置电源的 hub。

选了 ORICO HF7U-3P-BK

#4 楼 @ike 能跑下最后的那个脚本检测下 hub 的稳定性不?现在不敢随便采购了,怕有坑。。。

@chenhengjie123 不着急我元旦假期之后把,设备没在身边。

#6 楼 @ike 好的,不着急。谢谢你~

关于你的问题,据我的经验,跟 usb-hub 没啥太大关系,一般主流的 USB-hub 就可以了(一个 USB-HUB 设计不会超过 7 个口,貌似跟底层协议有关)。20 分钟断一次要看一下是不是跟你的安卓手机有关,我之前发现一些手机就是坑爹的会断连,还有一些手机限制 shell 的命令会导致平台运行不正常 。目前我这里 20 台手机跑一个星期都没啥问题。不过每上一台新手机总要看一下会不会有问题。

#8 楼 @0x88 我这边用了排除法,同样的手机,同样的电脑,用我们以前买的 4 口 USB hub 很稳定,至少 24 小时不会掉线一次,但换了新买的 A3H4(也是 4 口)后就会频繁掉线。换过了其它手机,也是一样,基本排除手机的问题。

之所以认为是 hub 和 ubuntu 的兼容性问题,是因为 windows 和 mac 上这个 hub 也是很稳定的,同样 24 小时不会掉线一次。

#9 楼 @chenhengjie123 你可以试下 dmes|grep usb 看下有没有 disconnect 或者 error,如果有就是 USB 有问题,如果没有就是手机的系统问题,还有你的 USB-HUB 有没有外置电源?ubuntu 在 hub 这一块是没问题的,以前做过的 ubuntu 硬件项目最多的问题也是 USB-HUB 本身的问题:USB 连接过多会拉低电压导致 USB 出现异常,对于这种问题加外部电源就能解决。PS:我用的是 ACASIS 这款 USB-HUB。附上淘宝链接:https://item.taobao.com/item.htm?spm=a230r.1.14.283.wxeEZU&id=543180665117&ns=1&abbucket=20#detail

#10 楼 @0x88 谢谢你的提醒。

我采用了 lsusb 检查 usb 连接设备的情况,也通过监控 ubuntu 的 /var/log/syslog 查看有没有 usb disconnect 或者 error 的日志,但都没有发现 disconnect 或者 error 。掉线时除了 adb devices 找不到设备外,lsusb 上显示设备是正常连接的 。并且不做任何操作,adb 会自动重新连上那台设备。

usb hub 有外置电源,测试的时候也有外接电源。

所以问题定位在 adb 上了。但用旧的 usb hub 一直都很稳定的,所以也只能定位在 hub 和 adb 的兼容性问题上了。。。

真不好说是什么原因,还真得看下详细的 syslog。还有你可以试下我用的这款 USB-HUB。

#12 楼 @0x88 好,后面试试你这款 USB-HUB ,先谢啦~

#13 楼 @chenhengjie123 为什么我运行会是这样

C:\Users\Administrator>adb -a -P 5037 fork-server server
reply fd for adb server to client communication not specified.
Android Debug Bridge version 1.0.36
Revision 302830efc153-android

 -a                            - directs adb to listen on all interfaces for a connection
 -d                            - directs command to the only connected USB device
                                 returns an error if more than one USB device is present.
 -e                            - directs command to the only running emulator.
                                 returns an error if more than one emulator is running.
 -s <specific device>          - directs command to the device or emulator with the given
                                 serial number or qualifier. Overrides ANDROID_SERIAL
                                 environment variable.

好像没有这个参数啊

#8 楼 @0x88 你好,我想问下,你这 20 部手机是接在一台服务器上吗???我用的是 ubuntu 笔记本电脑做的服务器,最多支持 9 个 usb 接口连接,请问你用的是什么?谢谢了

#14 楼 @appium_test 我这里是正常的。

难道是 adb 版本的原因?

#15 楼 @liuang68 就一台装了 ubuntu 的普通 PC 电脑😂 ,在 USB 口接 usb-hub。

#17 楼 @0x88 嗯,我现在的 9 部手机就是接的 usb-hub,但是接到 10 的时候,电脑就提示不能接了。你的可以接 20 台???

#18 楼 @liuang68 这个跟你 USB 供电有关,接多个 usb 后会拉低 usb 电压 (USB 电压是 5V,拿个万用表测一下就知道了,如果低于 4.8V USB 接口就会工作不正常),一定要接外部电源!!!

hello,@chenhengjie123 我看了下你的教程,还是有点懵,我现在在 ubuntu 的一台机器上部署了 stf 服务,我要是做扩展的话,首先再准备一台 ubuntu 机器,问题来了,我需要在这台新的机器上部署 STF 环境吗??和第一台环境一致吗?还有就是,那个 provider 是在哪台机器部署呢?我现在对流程还是不清楚,sorry

#19 楼 @0x88 嗯,我用的 usb-hub 都是有独立电源的,目前用了两个,这两个型号不一样,会不会存在兼容问题了

#21 楼 @liuang68 如果是采用 provider 的方式,那就需要。provider 是 stf 的一部分。如果不想安装 stf ,那么可以采用 adb server 的方式,provider 在第一台 Ubuntu 上对应启动一个就可以了。

#23 楼 @chenhengjie123 我看到你上面说的 provider 有缺点,那这两种方式,从维护和稳定方面来讲的话,哪个比较好呢?adb server 的方式,就是我在第二台机器上搭建一下,然后再第一台 ubuntu 上对应启动就可以吗?

#23 楼 @chenhengjie123 我现在是用,手机 root 后进行命令操作,使用的是 setprop service.adb.tcp.port 5555,然后 start adbd 的方式来连接的手机,这样连接,24 小时会断,而且也是比较卡顿的,操作起来,不知道你说的 adb server 是怎么样的了

我这样也遇到过 hub 的问题,非常奇葩,dell optiplex 3020,ubuntu 系统接 hub,最多识别 9 台手机,再多识别不了,更奇葩的是,dell optiplex 990 ubuntu 可以识别 20 台以上的手机,而 3020 装 windows 系统没有任何问题,所以感觉是 ubuntu 的 usb 驱动有问题。

不好意思哈,我有点能说,我看了一下午,似乎明白了一点,我现在做到
想请教下,你的 Linux 主机上启动对应的 stf provider,这个 provider 是 stf 自带的组件还是后期加的呢?

我现在还是没明白,你的 Linux 主机和 Windowns 是如何关联起来的?在同一个网络环境下吗?还是怎么做的

#26 楼 @blueshark 这个不好说是驱动问题,如果驱动有问题应该所有的机器都会出现,个人认为是否你的 dell optiplex 3020 的硬件 USB 接口的问题?如果 USB 总线不支持识别多个或者做了限制,那也是有可能的。

#29 楼 @0x88  问题是 3020 装了 windows,adb 就可以识别超过 9 台的手机,所以应该是 ubuntu 系统的问题

#28 楼 @liuang68 两台设备网络上互通(能 ping 通)就可以了。

stf 本身由多个组件构成,官方给的 stf local 实际上也是启动了这多个组件。provider 本身是多个组件中的一个。

你可以理解为你装了 stf ,就有 provider 了。provider 不能单独安装,它是 stf 的一部分。

ssk(飚王)[https://item.jd.com/637661.html😂],现在掉线厉害 。

#31 楼 @chenhengjie123 你好,我想问下,我现在有 2 台 linux 机器,一台是搭建了 STF 的服务,现在想做扩展,原因就是一台机器外接 usb 上限,那我现在,在第二台 linux 机器,需要做些什么操作呢?


你好,我执行了这样的命令:
stf provider --name "provider-mac_4" --connect-sub tcp://10.100.75.195:7250 --connect-push tcp://10.100.75.195:7270 --storage-url http://10.100.75.195 --public-ip 10.100.75.195 --min-port=35000 --max-port=40000 --heartbeat-interval 20000

是我哪里理解错了吗????本地都没办法访问 stf 页面了,求大 v 指导

#31 楼 @chenhengjie123 你好,我现在测试两台机器是可以 ping 通的,那我是不是在那台搭建 STF 服务的机器上执行以下命令就可以的:
stf provider --name "provider-windows_3" --connect-sub tcp://10.100.72.195:7250 --connect-push tcp://10.100.72.195:7270 --storage-url http://10.100.72.195 --public-ip 10.100.72.195 --min-port=30001 --max-port=35000
这个命令是我复制你上面的,我只是改了改 IP 地址,ip 为另一台机器的地址,但是,我在页面该输入什么来访问呢???我自己尝试了很多遍,都无法访问。我插上手机,貌似也存在问题,下图:

#35 楼 @liuang68 你的 provider 命令少参数吧,还需要指定--screen-ws-url-pattern,这个是最重要的屏幕图像传输的参数,如果你想用 nginx 反向代理屏幕图像的传输,还要在 nginx.conf 里配置一下代理的参数。可以参考https://testerhome.com/topics/7062 。还有,你的手机是 offline 怎么可能识别

#35 楼 @liuang68

  1. 端口号你要根据自己服务具体配置的端口号来配置哦,我上面的示例是根据我自己 triproxy dev 的端口配置来配置的。如果你用 stf local 来启动 stf ,可以看下日志或者源码里面 triproxy dev 具体的端口配置情况。
  2. 先确认下,你用的是我示例中 mac 的方法还是 windows 的方法?看你在 stf 服务的机器上多开 provider ,我能理解为你用的是 windows 的方法?如果是,那就漏了 adb host 这个参数。除了 adb host 要用 windows 主机的 ip 地址,其它还是用 stf 服务所在主机的 ip 地址。

#37 楼 @chenhengjie123 我是 2 台 linux 的机器,并不是采用你的 windows 的方法的,你好,您能加下我的 Q 吗,我觉得 q 沟通起来会更方便一些,万分感激

恒洁姐姐真是套路← ←
怎么样,实验了一个月以后,有得到相关为什么设备会在一定时间内以后就会 offline 或者直接读取不到的线索吗~

#39 楼 @Anikikun 额,哪里套路了。。。

最终结论是 usb hub 芯片和 linux 上的 adb server 有兼容性问题。

实验方法:

  1. 准备好 3 个脚本,一个脚本就是上面的一直检测 adb 连接是否被断开,第二个是每隔 1s 打印 adb devices ,第三个是每隔 1s 打印当前连接的 usb 设备列表(类似 lsusb)。
  2. 使用同型号的 hub ,分别在 windows 、mac、ubuntu 上连接手机(手机已试验过和 stf 能稳定连接),并通过 adb server 或者 stf provider 连到同一个 stf 平台。
  3. 在三个操作系统上同样运行上述三个脚本,过约 24 小时候查看脚本运行情况。

在 mac 和 windows 上,手机未出现掉线,adb devices 和 lsusb 输出都正常
在 ubuntu 上,手机掉线超过 3 次,每次掉线持续约 5-10s(通过 adb devices 脚本日志看出),但每次掉线时 lsusb 设备列表没有变化。

最终只能说这个 hub 和 linux 上的 adb server 有兼容性问题了。。。

#40 楼 @chenhengjie123 额。不容易。
那这么看来,反而 windows 还要比 linux 稳定?这真是不太科学。
然后,你用 provider 的方式来管理的话,也算是把 adb 的压力均摊了,可以弄多几台 Windows。

#41 楼 @Anikikun 只能说这个 hub 和 windows 兼容性比 linux 的好,估计是厂家专门优化过兼容的吧。

可以的话还是想多弄几台 Linux ,windows 上用 npm 装 appium 不那么方便,而且容易出现各种编码问题。而且 windows 一次性只能接 9 台 android 设备,超过 9 台后新的就识别不了,略坑。。。

blueshark 回复

你好,你的问题解决了么,我前几天 ubuntu 上也是,最多识别 12 个,有什么好的解决方法么

美年达 回复

我这里还没找到好的办法

好 麻烦问下 我现在的 ADB 版本是 1.0.39
fork-server serve 这个不支持了...麻烦有别的方法吗 因为不是做移动端的现在让我弄这个 太要命了..

张俊明 回复

建议找下 android 官方的文档吧,或者 adb --help 查下。我相信这个机制不会消失的,有可能只是命令改了而已。

张俊明 回复

貌似 fork-server 没有改,只是-a 参数不能用了而已。如果真要用 39 版本那就去看源码怎么改的,不行就用回 1.0.32 版本。



楼主你好,我按照帖子的方法搭建成功了。master 实在 ubuntu 上,如第一张图。手机是插在 windows 机器上的如第二张图。但是一直提示 Providing all 0 of 1 device(s),这是哪个出问题了呢?PS:重启,重装都尝试了一遍,手机和 USB 接口也都换了,但是还是不行。

Allen 回复

你好,遇到了同样的问题,最后解决了么?

鱼肚白 回复

检查下安装 stf service 这个 apk 的时候是不是没有允许安装?

陈恒捷 回复

你好,这句没太理解,你的意思是 npm install stf 的时候有没有报错么?

陈恒捷 回复

我用 docker 版本也是报同样的错误😅

鱼肚白 回复

你现在的问题是 adb devices 可以显示设备,但 Provider 无法使用设备。

adb devices 可以显示设备说明你的机器和设备之间的连接是没问题的,provider 无法使用,意味着 provider 无法和手机上的 stf service 连接,所以无法使用(这个 service 用于传图像信息等)。

当 provider 开着的时候,连接手机会自动安装 stf service 这个 android 应用,你可以往这个方向检查下这个应用是不是没有被成功安装。

陈恒捷 回复

这个逻辑啊。。那么如果是 master 启动 stf local,直接在 master 上插手机的话,手机上是否会安装 stf service 这个 Android 应用呢?

0x88 回复

好哒 谢谢

鱼肚白 回复

您好,我也遇到了之前这个问题,不知道您解决了吗。

土豆 回复

@appium_test 你好,我的 adb 的版本和你一样,想问下这个问题你解决了么

@liuang68 ,能指点一下 provider 没有执行的原因么?

在配置 master 和 slave 时候,slave 暴露端口的命令【adb -a -P 5037 fork-server server】如果失败的话。可以执行命令【adb -P 5037 -a nodaemon server】
原命令的失败是因为 adb 的更新,可以使用新的 adb 版本,使用【adb -P 5037 -a nodaemon server】。

wanxiaoqiang 回复

解决了。。stf local 启动时,不加具体 ip,用 127.0.0.1 就行了,原理未知,你可以试试。

Allen 回复

你这个问题怎么解决的哦

Awesome 回复

最后多了双引号

请问 STF 的前端页面如何能显示成中文的呢?在有的帖子上看显示的语言就是中文的。谢谢了!

yefengjun 回复

有语言可以选择的,印象中在右上角的设置菜单里。你试试?

陈恒捷 回复

在设置里看到了,谢谢。安装好没仔细看哎...

您好,因为版本的的原因

adb -a -P 5037 fork-server server

这个命令我无法执行,改用

adb -P 5037 -a nodaemon server

这个命令执行了 没有任何反应

无言祖 回复

不大明白你截图里的 本机地址 具体是指哪台机器。

adb host 需要填 windows 主机,也就是你运行 adb -P 5037 -a nodaemon server 这个命令的主机地址。

陈恒捷 回复

本机地址就是 window 主机的 IP
我在 windows 机器上执行 adb -P 5037 -a nodaemon server 这个命令 没有反应(如上图)

无言祖 回复

从 provider 日志来看,访问不到 172.31.3.21 主机的 5037 端口。

通过类似 lsof 之类的工具看下这个端口是不是 adb 在监听?


provider 连接不到设备,这个问题该怎么解决呢

回复

emulator-5554 处于 offline 状态,确认下是不是掉线了?
192.168.107.101:5555 ,需要查看下更详细的日志看 adb 连接或者 stf service 的安装有没有问题,建议直接把从开始启动 provider 到你截图的这一行所有日志都附上来,这样才能全面地分析。

请问不在不同局域网下怎么连接机器,比如我 stf 部署在 linux 机器上,我 window 上 usb 连接机器,linux 上怎么连接机器。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册