解决mux阻塞的方法,并且保持mux自身长连接(附一个go程序) #1453
Replies: 4 comments 1 reply
-
Why not use bash directly 😒 while true; do curl Google.com ; sleep 2 ; done |
Beta Was this translation helpful? Give feedback.
-
不使用curl命令的原因是:curl请求结束后会立即断开,不能维持长连接,进而导致mux无法维持长连接,而且安卓设备不支持curl命令 |
Beta Was this translation helpful? Give feedback.
-
this affects nothing. problem 1: you should make a call (such as http) to your inbound. // no
conn, err := net.DialTimeout("tcp", "223.5.5.5:80",time.Second*4)
// yes
client.Do(...) problem 2: vary of requests makes the big blocking instead. problem 3: you shouldn't do a keepalive mux conn as it is designed to wait the server response. |
Beta Was this translation helpful? Give feedback.
-
Maybe the problem is with ClientWorker.monitor function? func (m *ClientWorker) monitor() {
timer := time.NewTicker(time.Second * 16)
defer timer.Stop()
for {
select {
case <-m.done.Wait():
m.sessionManager.Close()
common.Close(m.link.Writer)
common.Interrupt(m.link.Reader)
return
case <-timer.C:
size := m.sessionManager.Size()
if size == 0 && m.sessionManager.CloseIfNoSession() {
common.Must(m.done.Close())
}
}
}
} It seems to close the muxed connection if there isn't an ongoing session in it every 16 seconds. I changed it to a longer interval, and it still works after idling for half an hour. Why is it in there, though? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
我们都知道,mux有阻塞问题(废话),碰到网络丢包或响应太慢时会导致卡死,要过一段时间才会恢复,这个问题有反复提及,然而,mux的阻塞发生在tcp层,无法解决,而mux长连接的功能似乎作者没理,所以自己写了一个简单的go程序实现。
首先,在客户端先设置Policy 本地策略,将connIdle值设置为3,目的是控制阻塞发生时的时长,这样设置可以解决mux阻塞感知,但是会导致mux无法保持长连接,如果3秒内没有任何连接,mux会关闭,显然,这个时长太短了,我们希望mux连接能够一直维持,这样不管什么时候有新的连接,都能降低连接延迟,提高使用体验。
我的解决方案是:写一个go程序,每隔2秒发送一次tcp连接,这样mux连接就能一直维持,达到长连接的效果,下面是实现源码:
程序项目地址:https://github.com/wenzhuning/tcpk0
package main
import (
"fmt"
"net"
"time"
)
func doTask() {
time.Sleep(1 * time.Second)
main()
}
func main() {
for {
conn, err := net.DialTimeout("tcp", "223.5.5.5:80",time.Second*4)
if err != nil {
fmt.Println("请求失败", err)
doTask()
}else{
fmt.Println("请求成功", conn)
}
}
}
首先要说明,这个程序会不断的发送tcp连接用来维持mux的长连接,会导致设备额外的耗电量,程序本身不会自动停止,如果不想用了可以手动停止(linux或安卓端执行 killall tcpk0即可关闭)。
有人会说这段代码里没有close(),会不会导致连接数量过多,这个是不会的,因为我设置的connIdle值只有3秒,3秒后多余的连接会被xray关闭,并且为了维持mux的长连接,也不能添加close()。
注意:connIdle值在客户端设置就行了,服务端不要设置。
由于我学习go只有2到3天,这段代码也是参考网络上的实例程序,我更希望xray的维护者能直接在xray中添加mux长连接功能。
Beta Was this translation helpful? Give feedback.
All reactions