我想根据某种状态来控制一个监听器,假设我的程序将在文件内容为1时监听,而在内容为0时不监听。

问题在于,一旦初始化了侦听器,就无法告诉他拒绝连接。只有“接受”状态;我必须关闭监听器。

所以我找到了一种使用以下代码的方法,但是我觉得这不是一个好方法,因为我使用的是全局变量,通常这不是一个好主意。

有更好的方法吗?

var healthStatus bool

func listen(l net.Listener, port int) {
    var err error
    l, err = net.Listen("tcp", ":"+strconv.Itoa(port))
    if err != nil {
        panic(err)
    }

    defer l.Close()
    for {
        if healthStatus == false {
            _ = l.Close()
            return
        }
        logrus.Debug("Going to listen !")
        conn, err := l.Accept()
        if err != nil {
            panic(err)
        }
        go func(c net.Conn) {
            _ = c.Close()
        }(conn)
        }
    }


func main() {
    healthStatus = true

    var listener net.Listener
    var isListening = false

    for {
        logrus.Debug("Performing checks...")
        healthStatus = healthcheck()
        

        if healthStatus {
            if !isListening {
                isListening = true
                //Restart listener
                go listen(listener, config.port)
            }
        }

        if !healthStatus {
            if isListening {
                isListening = false
            }
        }

        time.Sleep(time.Second * 10)
    }
}

编辑 : 带通道

package main

import (
    "net"
    "strconv"
    "time"
)

var listening = make(chan bool)

func listen(l net.Listener, port int) {
    var err error
    l, err = net.Listen("tcp", ":"+strconv.Itoa(port))
    if err != nil {
        panic(err)
    }

    defer l.Close()
    for {
        localstatus := <- listening
        if localstatus == false {
        _ = l.Close()
        return
    }
    conn, _ := l.Accept()

    go func(c net.Conn) {
    // Shut down the connection.
        _ = c.Close()
        listening <- true
    }(conn)
    }
    }


func main() {
    healthStatus := true

    var listener net.Listener
    var isListening = false

    for {
        healthStatus = healthcheck()
        

        if healthStatus {
            if !isListening {
                isListening = true
                //Restart listener
                go listen(listener, config.port)
            }
            listening <- true
        }

        if !healthStatus {
            if isListening {
                isListening = false
                listening <- false
            }
        }

        time.Sleep(time.Second * 10)
    }
}
分析解答

健康状况恶化时,请关闭侦听器。使用通道向accept循环发信号,这是完全关闭。

var listener net.Listener
var done chan struct{}
for {
    if healthcheck() {
        if listener == nil {
            var err error
            listener, err = net.Listen("tcp", ":"+strconv.Itoa(conig.port))
            if err != nil {
                panic(err)
            }
            done = make(chan struct{})
            go accept(listener, done)
        }
    } else {
        if listener != nil {
            close(done)
            listener.Close()
            done = nil
            listener = nil
        }
    }
    time.Sleep(time.Second * 10)
}

接受函数是:

func accept(l net.Listener, done chan struct{}) {
    for {
        conn, err := l.Accept()
        select {
        case <-done:
            return
        default:
        }
        if err != nil {
            panic(err)
        }
        go func(c net.Conn) {
            _ = c.Close()
        }(conn)
    }
}