英文:
Golang prevent channel from blocking
问题
我正在构建一个使用Websockets的服务器。目前,每个连接的客户端都使用两个goroutine,一个用于读取,一个用于写入。
写入的goroutine基本上会监听一个通道,以获取应该发送的消息,然后尝试将它们传递给客户端。
type User struct{
send chan []byte
...
}
func (u *User) Send(msg []byte){
u.send <- msg
}
问题是,从客户端A读取可能会导致向客户端B写入。
然而,假设与B的连接存在一些问题(例如,非常慢),并且它的发送通道已经满了。当前的行为是,尝试向通道添加消息会导致阻塞,直到有东西从通道中移除。
这意味着现在A要等到B的缓冲区不再满。
我想要这样解决:
func (u *User) Send(msg []byte) error{
select {
case u.send <- msg:
return nil
default:
// 通道的缓冲区已满。
// 当前无法写入。
// 需要适当的错误处理。
return fmt.Errorf("channel buffer is full")
}
}
基本上,我希望在缓冲区已满时进行错误处理,而不是阻塞。如何最好地实现这一点?
英文:
I am building a server that uses websockets.<br>
Currently every connected client uses two goroutines. One for reading and one for writing.
The writing goroutine basically listens to a channel for messages it should send and then tries to deliver them.
type User struct{
send chan []byte
...
}
func (u *User) Send(msg []byte){
u.send <- msg
}
Problem is, that a read from client A may cause a write to client B.
Suppose the connection to B has some problems however (e.g. very slow) and it's send channel is already full. Current behaviour is, that trying to add a message to the channel now starts blocking, until something is removed from the channel.
This means, that now A waits until B's buffer is no longer full.
I want to solve it somewhat like this:
func (u *User) Send(msg []byte) err{
u.send, err <- msg
if err != nil{
//The channels buffer is full.
//Writing currently not possible.
//Needs appropriate error handling.
return err
}
return nil
}
Basically instead of blocking I want error handling in case the buffer is full.
How do I achieve that best?
答案1
得分: 6
如ThunderCat在他的评论中指出的那样,解决方案是:
func (u *User) Send(msg []byte){
select{
case u.send <- msg:
default: //在这里处理错误
}
}
英文:
As ThunderCat pointed out in his comment the solution is
func (u *User) Send(msg []byte){
select{
case u.send <- msg:
default: //Error handling here
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论