在Go上重新连接EOF上的TCP [英] Reconnect TCP on EOF in Go
问题描述
//在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屋!