为了账号安全,请及时绑定邮箱和手机立即绑定

如何在没有比赛的情况下延长自动收报机的持续时间?

如何在没有比赛的情况下延长自动收报机的持续时间?

Go
白衣染霜花 2021-11-01 14:15:11
我正在尝试实现一个 keepAlive 机制。问题是我不知道如何在没有竞争的情况下替换保持活动的股票代码 (conn.keepAlive),因为keepAlive()方法总是从股票代码中读取。//errors not handled for brevityconst interval = 10 * time.Secondtype conn struct {    keepAlive time.Ticker    conn      net.Conn    mux       sync.Mutex}// replace replaces the underlying connectionfunc (cn conn) replace(newcn net.Conn) {    cn.mux.Lock()    cn.conn = newcn    // reset the ticker    cn.keepAlive.Stop    cn.keepAlive = time.NewTicker(interval)    cn.mux.Unlock()}func (cn conn) keepAlive() {    for {        <-cn.keepAlive.C        cn.mux.Lock()        cn.conn.Write([]byte("ping"))        var msg []byte        cn.conn.Read(msg)        if string(msg) != "pong" {            // do some mean stuff        }        cn.keepAlive = time.NewTicker(interval)        cn.mux.Unlock()    }}
查看完整描述

2 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

更简洁地实现这一点的一种方法是使用通道作为同步机制,而不是互斥锁:


type conn struct {

    sync.Mutex

    conn        net.Conn

    replaceConn chan net.Conn

}


// replace replaces the underlying connection

func (cn *conn) replace(newcn net.Conn) {

    cn.replaceConn <- newcn

}


func (cn *conn) keepAlive() {

    t := time.NewTicker(interval)

    msg := make([]byte, 10)


    for {

        select {

        case <-t.C:

        case newConn := <-cn.replaceConn:

            cn.Lock()

            cn.conn = newConn

            cn.Unlock()

            continue

        }


        cn.Lock()

        _ = msg

        // do keepalive

        cn.Unlock()

    }

}


查看完整回答
反对 回复 2021-11-01
?
富国沪深

TA贡献1790条经验 获得超9个赞

我最终得到了下面的代码。我对它的样子不太满意,但它确实有效。基本上我将复用器包裹在一个通道中,以便我可以对其进行选择。


const interval = 10 * time.Second


type conn struct {

    keepAlive time.Ticker

    conn      *net.Conn

    mux       sync.Mutex

}


// replace replaces the underlying connection

func (cn conn) replace(newcn *net.Conn) {

    cn.mux.Lock()

    cn.conn = newcn

    // reset the ticker

    cn.keepAlive.Stop

    cn.keepAlive = time.NewTicker(interval)

    cn.mux.Unlock()

}


func (cn conn) keepAlive() {

    lockerFn := func() <-chan struct{} {

        cn.mux.Lock()

        ch = make(chan struct{})

        go func() {

            ch <- struct{}{}

        }()

        return ch

    }

    for {

        locker := lockerFn()

        select {

        case <-cn.keepAlive.C:

            // unlock the locker otherwise we

            // get stuck

            go func() {

                <-locker

                cn.mux.Unlock()

            }()

        case <-locker:

            cn.conn.Write([]byte("ping"))

            var msg []byte

            cn.conn.Read(msg)

            cn.keepAlive = time.NewTicker(interval)

            cn.mux.Unlock()

        }

    }

}


查看完整回答
反对 回复 2021-11-01
  • 2 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信