小智 14
如果您不想实现自己的包装器,可以使用该netutil.LimitListener函数net.Listener包装: -
connectionCount := 20
l, err := net.Listen("tcp", ":8000")
if err != nil {
log.Fatalf("Listen: %v", err)
}
defer l.Close()
l = netutil.LimitListener(l, connectionCount)
log.Fatal(http.Serve(l, nil))
Run Code Online (Sandbox Code Playgroud)
这样做的诀窍是实现自己的net.Listener.我有一个听众的例子这里(见waitConn和WaitListener)跟踪连接(但不限制他们),你可以为灵感的实现中使用.它将形成如下形状:
type LimitedListener struct {
sync.Mutex
net.Listener
sem chan bool
}
func NewLimitedListener(count int, l net.Listener) *net.LimitedListener {
sem := make(chan bool, count)
for i := 0; i < count; i++ {
sem <- true
}
return &net.LimitedListener{
Listener: l,
sem: sem,
}
}
func (l *LimitedListener) Addr() net.Addr { /* ... */ }
func (l *LimitedListener) Close() error { /* ... */ }
func (l *LimitedListener) Accept() (net.Conn, err) {
<-l.sem // acquire
// l.Listener.Accept (on error, release before returning)
// wrap LimitedConn
return c, nil
}
type LimitedConn struct { /* ... */ }
func (c *LimitedConn) Close() error {
/* ... */
c.sem <- true // release
}
Run Code Online (Sandbox Code Playgroud)
基本上它正在做的是创建你自己的net.Listener实现,你可以给Serve只能在它获取信号量时调用底层的Accept; 如此获得的信号量仅在(适当包装的)net.Conn关闭时释放.注意,从技术上讲,这种信号量的使用对于go1.2 内存模型是正确的.在Go的未来版本中,更简单的信号量将是合法的.
| 归档时间: |
|
| 查看次数: |
9370 次 |
| 最近记录: |