在Go上重新连接EOF上的TCP [英] Reconnect TCP on EOF in Go

查看:1470
本文介绍了在Go上重新连接EOF上的TCP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  //在init func 
中,如果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秒尝试重新建立连接?

解决方案

Go有同步和沟通渠道,可以使用它们!

在一个循环中建立连接,并等待某种消息返回到某个频道。

  .. 。
errCh:= make(chan error)
for {
lsconn,err = net.Dial(tcp,logStashHost)
//检查错误!
去掉ReadLogStash(lsconn,errCh)
err =< -errCh
if err!= nil {
// bad error
break
}
//睡眠以重试退避?



func ReadLogStash(conn net.Conn,errCh chan error){
_,err:= io.Copy(os.Stderr, conn)
if err!= nil {
fmt.Println(err)
}
// io.Copy的一个无错误表示您已到达EOF。
errCh < - err
}

除非在ReadLogStash中有更多的功能,你可以直接使用io.Copy,并忘记整个函数,但是这种模式对你来说可能有用。


I have the following:

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

Then Two functions:

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)
    }
}

Where ReadLogStash is a running goroutine. If the other side closes, I get EOF. What would be a good implementation in ReadLogStash to have it attempt to reestablish the connection every X seconds when it gets an EOF?

解决方案

Go has channels for synchronization and communication, use them!

Make your connection in a loop, and have it wait for some sort of message to come back on a channel.

...
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
}

Unless you have more functionality in ReadLogStash, you can probably just use io.Copy inline, and forget the entire function, but this pattern may come in useful for you anyway.

这篇关于在Go上重新连接EOF上的TCP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆