一尘不染

在Go中的EOF上重新连接TCP

go

我有以下几点:

    //In an init func
    if logStashHost != "" {
        lsconn, err = net.Dial("tcp", logStashHost)
    }
    ...
    ToLogStash(rec, lsconn)

然后两个功能:

func ReadLogStash(conn net.Conn) {
    buffer := make([]byte, 256)
    for {
        _, err := conn.Read(buffer)
        if err != nil {
            fmt.Println(err)
        } else {
            fmt.Println(buffer)
        }
    }
}

func ToLogStash(r *logrow.Record, conn net.Conn) {
    b, err := json.Marshal(r)
    if err != nil {
        fmt.Println(err)
        return
    }
    _, err = fmt.Fprintln(conn, string(b))
    if err != nil {
        fmt.Println(err)
    }
}

其中ReadLogStash是正在运行的goroutine。如果另一侧关闭,我得到EOF。ReadLogStash中的一个好的实现是什么,当它获得EOF时,尝试每X秒重新建立一次连接?


阅读 199

收藏
2020-07-02

共1个答案

一尘不染

Go有同步和沟通的渠道,请使用它们!

使您的连接处于循环状态,并让它等待某种消息返回通道。

...
errCh := make(chan error)
for {
    lsconn, err = net.Dial("tcp", logStashHost)
    // check error!
    go ReadLogStash(lsconn, errCh)
    err = <-errCh
    if err != nil {
        // bad error
        break
    }
    // sleep to backoff on retries?
}
...

func ReadLogStash(conn net.Conn, errCh chan error) {
    _, err := io.Copy(os.Stderr, conn)
    if err != nil {
        fmt.Println(err)
    }
    // a nil error from io.Copy means you reached EOF.
    errCh <- err
}

除非您在ReadLogStash中具有更多功能,否则您可能只能使用io.Copy内联,而忘了整个功能,但是无论如何,此模式可能对您很有用。

2020-07-02