谷歌 FCM 还是建议不要走直连

2023-08-27 21:44:40 +08:00
 pagxir
周末看了手机*#*#426#*#*的 FCM 诊断信息,心跳一直保持在 230 秒。手机是一台备用老手机,很多年了,,一般都是冲完电放一边,电池续航很差了。

心跳一直在 230 秒感觉很费电,很影响续航。一开始以为是 wifi 网络问题,以为是 NAT 时间过短,就试着在路由器上转发一下增加一下 tcp 的 keepalive 。

于是在路由器上执行:
iptables -t nat -A PREROUTING -p tcp --dport 5228 -i wlan0 --to DNAT 192.168.1.1:5222
socat TCP-LISTEN:5222,fork,reuseaddr TCP:64.233.189.188,keepcnt=3,keepidle=300,keepintvl=60
然而半天测试下来,并没有啥用。

从抓包看,最后的断开地方,看到手机有发送 client heart beat, 但是收不到应用层的 ACK (但是看到 TCP 的 ACK 是有的,偶尔还看到 client heart beat 后还有接收到 server heart beat )。

初步觉得国内虽然 mtalk.google.com 没有直接阻断,但是还是有干扰,要么是靠近国内的 FCM 服务器不太稳定。

最后,尝试在路由器上建立 ipsec 隧道,然后让连接美国的 FCM 服务器 mtalk.google.com/74.125.137.188, 然后 ipsec 是走 udp 封装,所以就一直 ping 避免 UDP 的 NAT 失效。 目前测试下来,FCM 连接 7 个小时没有断开,并且心跳已经能够从 230 升到了 770,并且感觉手机电量也不再崩的那么快了。

所以,我觉得路由器上通过 UDP(udp2raw)转发 TCP/5228 流量应该是个不错的方案,比起直连好很多。

至于,移动数据网络上,我测试把 mtalk.google.com 域名解释道国内的机器上,然后在国内机器通过 UDP 把 TCP/5228 转发出去,测试下来心跳时间可以稳定到 1100 秒。

结论:不要在国内放任 FCM 直连,否则会影响续航以及推送的及时性。
3062 次点击
所在节点    分享发现
13 条回复
PowerDi
2023-08-28 08:40:46 +08:00
直接开代理就行了吗
elechi
2023-08-28 09:05:50 +08:00
用 4G 咋办?
pagxir
2023-08-28 09:16:21 +08:00
@elechi 我现在办法是,挂代理( ss/ray 等),然后在代理中 hook DNS ,将 mtalk.google.com 解析到国内的 VPS/挂机宝,然后在那个挂机宝/VPS 上作中转( UDP/udp2raw )处理。也就是 mtalk.google.com 既不走代理也不走直连,而是单独中转。
pagxir
2023-08-28 09:20:11 +08:00
@PowerDi 可能 TCP 承载的代理不会很稳定,可以在路由器上用 gost 走 quic/kcp 类的承载转发一下。如果确认 TCP 承载是稳定的直接走代理也可以。
ParanoidAndroid
220 天前
@pagxir 你好,请教一下这里为什么是做 UDP 中转呢?使用 Haproxy 来转发 TCP:5228 的流量可以吗?
pagxir
220 天前
这个问题的原因是一是某些 ISP 的 NAT 时间过短,二是 gcm 服务器位于海外收众所周知的干扰。要解决这两问题即可以,NAT 问题可以用不需要 nat 的 ipv6 来解决(不过国内大部分的 ISP 提供 DNS 没有提供 ipv6 接入/不是 ipv6 优先,所以不会解释 mtalk.google.com 到 AAAA 记录,所以需要改用 8.8.8.8 的或者手动设置 mtalk.google.com 的 AAAA 记录), 而这里建议用 UDP 原因是没有 TCP RST 的干扰,并且可以自动重新而 tunnel 不断。自己可以根据自己情况测试,用 haproxy 进行 v4 转 v6 应该也是可行的。我后来试过,路由器上用 socat 并且将 keepalive 设置成 120 秒,实际上也是可以的,也就是我的宽带的 nat 时间过短(毕竟是移动的宽带)
pagxir
220 天前
@ParanoidAndroid #5 国内有 ipv6 的话可以将 mtalk.google.com 绑定到 2404:6800:4008:c06::bc
ParanoidAndroid
219 天前
@pagxir 也就是说远端的 mtalk.google.com:5228 可以通过 quic 与中转服务器交互数据,之后中转服务器再通过 TCP 返回给手机客户端吗?新手刚接触这里,理解可能不到位,请见谅😂
laod911
93 天前
@pagxir 大佬,尝试了绑定 ipv6 地址 ,WiFi 下也不行,我遇到了和你类似的情况,可以详细说说 udp 转发 tcp5228 吗
laod911
93 天前
@pagxir 断开的原因我估计是因为在 nat 下没法保持 tcp 长连接吧,这样做端口转发的话 手机→vps 的连接不还是 tcp 连接吗,怎么能保持长连接呢,不太懂,望大佬教教
pagxir
92 天前
ipv6 没有 nat ,理论上不需要改动,但是毕竟经过了 GFW ,所以可能受到干扰。至于 ipv4 ,某些网络的 nat 会话保持时间比较短,比如只有 2 分钟,所以通过 tcp 转发并且在路由器上打开 keepalive 可以让 nat 会话刷新,避免失效。当然了,这时候刷新 nat 会话一部分从手机转移到路由器,耗电也只是从手机转到路由器,不过一般路由器直接插电,所以问题不大。
@laod911
laod911
84 天前
@pagxir 没用软路由,比较关注你说的移动网络下的解决办法,感觉是一劳永逸。是手机→vps (通过 tcp 协议)的 5228 端口,vps 的通过 udp 监控转发来自 5228 端口的 tcp 流量→fcm 服务器,吗? 那这样手机→vps 还是 tcp 协议,不是仍然无法保持长连接吗?(* ̄︶ ̄)
pagxir
84 天前
@laod911 #12 那样做没有意义,因为虽然 fcm 没有断,但是 UDP 的会话保持时间比较短,导致为了维持会话有效需要缩短发送保活包的时间这会影响功耗。所以还是直接使用 TCP ,所以应该是 TCP/ipv6, 连不上然后是 TCP/ipv4 ,最后试试 UDP/ipv6 。因为 ipv6 不需要 nat

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/968701

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX