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()
}
}
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()
}
}
}
- 2 回答
- 0 关注
- 144 浏览
添加回答
举报