-
Notifications
You must be signed in to change notification settings - Fork 28
Open
Description
背景
当 keepOnline 选项开启时,本工具会在 keepAliveLoop 中定期发送 HTTP 请求至 https://www.tsinghua.edu.cn/ / https://www.baidu.com/,在正常情况可以持续保持在线状态。
Lines 207 to 267 in e42c2fd
| func keepAliveLoop(c *cli.Context, campusOnly bool) (ret error) { | |
| logger.Infof("Accessing websites periodically to keep you online") | |
| accessTarget := func(url string, ipv6 bool) (ret error) { | |
| network := "tcp4" | |
| if ipv6 { | |
| network = "tcp6" | |
| } | |
| netClient := &http.Client{ | |
| Timeout: time.Second * 10, | |
| Transport: &http.Transport{ | |
| DialContext: func(ctx context.Context, _network, addr string) (net.Conn, error) { | |
| logger.Debugf("DialContext %s (%s)\n", addr, network) | |
| myDial := &net.Dialer{ | |
| Timeout: 6 * time.Second, | |
| KeepAlive: 0, | |
| FallbackDelay: -1, // disable RFC 6555 Fast Fallback | |
| } | |
| return myDial.DialContext(ctx, network, addr) | |
| }, | |
| }, | |
| } | |
| resp, ret := netClient.Head(url) | |
| if ret != nil { | |
| return | |
| } | |
| defer resp.Body.Close() | |
| logger.Debugf("HTTP status code %d\n", resp.StatusCode) | |
| return | |
| } | |
| targetInside := "https://www.tsinghua.edu.cn/" | |
| targetOutside := "https://www.baidu.com/" | |
| stop := make(chan int, 1) | |
| defer func() { stop <- 1 }() | |
| go func() { | |
| // Keep IPv6 online, ignore any errors | |
| for { | |
| select { | |
| case <-stop: | |
| break | |
| case <-time.After(13 * time.Minute): | |
| _ = accessTarget(targetInside, true) | |
| } | |
| } | |
| }() | |
| for { | |
| target := targetOutside | |
| if campusOnly || settings.V6 { | |
| target = targetInside | |
| } | |
| if ret = accessTarget(target, settings.V6); ret != nil { | |
| ret = fmt.Errorf("accessing %s failed (re-login might be required): %w", target, ret) | |
| break | |
| } | |
| // Consumes ~5MB per day | |
| time.Sleep(3 * time.Second) | |
| } | |
| return | |
| } |
然而,在某些特殊情况下(如:校园网因某种特殊原因被暂停使用,然后被恢复使用,且在外地出差无法手动重新认证),目前的实现似乎未能实现自动重新认证。
潜在解决方案
选项一:添加新的命令行参数(如:--auto-reauth)
该参数与 --keepOnline 同时使用,当用户添加该参数时,可支持断线重连功能,即:当 keepAliveLoop 遇到错误后,重新进行认证操作。另外,可以添加指数退避策略防止过多的认证请求。
选项二:直接为 keepAliveLoop 添加断线重连功能
同上,当原始的 keepAliveLoop 失败时,说明校园网已掉线(可能是欠费或其他特殊原因),则重新认证。选项二的副作用是:改变了 keepAliveLoop 函数的语义(由 仅保持在线状态 变为 保持在线状态且断线重连)
其他
如果作者觉得合适的话,我可以协助实现该功能。
相关讨论
Metadata
Metadata
Assignees
Labels
No labels