所以我正在使用gorillas websocket库,我正在构建一个websocket服务器,当我收到一个连接时,我创建了2个例程,一个用于读取来自客户端的传入消息,另一个用于侦听发送到该频道的即将发送的消息然后将它们发送给客户。
func (p *Player) EventLoop() {
l4g.Info("Starting player %s event loop", p)
go p.readFromSocket()
go p.writeToSocket()
//blocks until we receive an interrupt from the read channel
<-p.closeEventChan
p.cleanup() //nothing else to do so lets cleanup
}
func (p *Player) writeToSocket() {
for m := range p.writeChan {
if p.conn == nil {
break
}
if reflect.DeepEqual(network.Packet{}, m) == true {
break
}
if err := p.conn.WriteJSON(m); err != nil {
break
}
}
p.closeEventChan <- true
}
func (p *Player) readFromSocket() {
for {
if p.conn == nil {
break
}
m := network.Packet{}
if err := p.conn.ReadJSON(m); err != nil {
break
}
}
p.closeEventChan <- true
}
func (p *Player) Cleanup() {
//make sure the channels get a close message which will break us out of the go routines
close(p.writeChan)
close(p.closeEventChan)
//only close the connection if we have a connection
if p.conn != nil {
p.conn.Close()
p.conn = nil
}
}
我的问题是,如果我们离开readFromSocket()
循环Cleanup()
被调用,但我们永远不会离开writeToSocket()
循环!在这个go playground https://play.golang.org/p/49bh7bbbG-
我们如何解决这个问题呢?如果我们离开writeToSocket()
循环,我们也会离开readFromSocket()
循环和副vesa?
我的印象是,这会像在频道(close(p.writeChan)
)上呼叫关闭一样,会发送频道接受的默认值
答案 0 :(得分:3)
您通常可以使用共享退出渠道执行此操作,并进行一些计数。
func (p *Player) writeToSocket(quit <-chan struct{})
defer func() {
p.closeEventChan <- true
}()
for {
select {
case <-quit:
return
case m := <-p.writeChan:
// Do stuff
// Case where writeChan is closed, but quit isn't
default:
return
}
}
}
func (p *Player) readFromSocket(quit <-chan struct{})
defer func() {
p.closeEventChan <- true
}()
for {
select {
case <-quit:
return
default:
// Do stuff
}
}
}
func (p *Player) EventLoop() {
l4g.Info("Starting player %s event loop", p)
quit := make(chan struct{})
go p.readFromSocket(quit)
go p.writeToSocket(quit)
//blocks until we receive an interrupt from the read channel
<-p.closeEventChan
close(quit)
// This is superfluous here, but in a different case
// you loop over the remaining number of workers using a NumWorkers variable
for i := 0; i < 1; i++ {
<-p.closeEventChan
}
p.cleanup() //nothing else to do so lets cleanup
}
这里的想法是: