У меня есть клиент, который отправляет (получает) данные на (с) сервера.Код клиента похож на:
conn, _ := net.Dial("tcp", "127.0.0.1:3456")
reader := bufio.NewReader(conn)
writer := bufio.NewWriter(conn)
for true {
writer.write(data)
reader.read()
}
Теперь предположим, что сбой сервера часто приводит к неисправности conn
.Это будет означать, что методы write
и read
в цикле for
ничего не сделают и просто вернут error
.Даже если сервер снова включится через несколько секунд, клиентский код цикла for
не сможет связаться с сервером, поскольку conn
неисправен.
Я пытаюсь достичь следующего: Пусть клиент продолжит работу, когда сервер снова включится. Для этого я придерживаюсь следующего подхода:
func fixConnection(conn *net.Conn, reader **[]bufio.Reader, writer **[]bufio.Writer) net.Conn {
for true {
oneByte := make([] byte, 1, 1)
reader := bufio.NewReader(*conn)
_, err := reader.Read(oneByte)
if err != nil {
for true {
var tmpConn net.Conn
tmpConn, err = net.Dial("tcp", "127.0.0.1:3456")
if err == nil {
*conn = tmpConn
*reader = bufio.NewReader(*conn)
*writer = bufio.NewWriter(*conn)
}
time.Sleep(time.Millisecond * 100)
}
} else {
reader.UnreadByte()
time.Sleep(time.Millisecond * 500)
continue
}
}
}
, а затем просто добавляю одну строку в клиенте:
conn, _ := net.Dial("tcp", "127.0.0.1:3456")
reader := bufio.NewReader(conn)
writer := bufio.NewWriter(conn)
// new line
go fixConnection(&conn, &reader, &writer)
for true {
writer.write(data)
reader.read()
}
Существует, по крайней мере, одна проблема с моим подходом: bufio
не является поточно-ориентированным, поэтому, пока fixConnection
меняет читателей (писателей), может возникнуть проблема.Есть ли способ решить эту проблему без использования sync.Mutex
перед работой с читателями / писателями.
Кроме того, есть лучший способ решить мою вышеупомянутую проблему.А именно, снова подключиться к серверу, когда сервер снова включится?Обратите внимание, что сервер может принимать подключения от нескольких клиентов в любой момент времени.