首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在没有比赛的情况下延长勾标的持续时间?

如何在没有比赛的情况下延长勾标的持续时间?
EN

Stack Overflow用户
提问于 2015-08-12 19:00:02
回答 2查看 359关注 0票数 0

我正在尝试实现一个keepAlive机制。问题是,我不知道如何在没有竞争的情况下替换“保持活动”代码( conn.keepAlive),因为keepAlive()方法总是从滴答符中读取。

代码语言:javascript
复制
//errors not handled for brevity
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() {
    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()
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-12 20:44:01

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

代码语言:javascript
复制
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()
    }
}
票数 0
EN

Stack Overflow用户

发布于 2015-08-12 20:07:40

最后我得到了下面的代码。我不太高兴它的样子,但它的工作。基本上,我在一个通道中封装了这个mux,这样我就可以在它上做一个选择。

代码语言:javascript
复制
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()
        }
    }
}
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31973345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档