server-go/client-readwriter.go

71 lines
1.4 KiB
Go
Raw Normal View History

2018-04-04 13:28:35 +00:00
package server
import (
"io"
"sync"
logging "git.loafle.net/commons/logging-go"
)
2018-04-04 13:50:34 +00:00
type ClientReadWriter struct {
2018-04-04 13:28:35 +00:00
ReadwriteHandler ReadWriteHandler
ReadChan chan<- []byte
WriteChan <-chan []byte
DisconnectedChan chan<- struct{}
2018-04-04 16:51:34 +00:00
ReconnectedChan <-chan Conn
2018-04-04 13:28:35 +00:00
ClientStopChan <-chan struct{}
ClientStopWg *sync.WaitGroup
}
2018-04-04 16:51:34 +00:00
func (crw *ClientReadWriter) HandleConnection(conn Conn) {
2018-04-04 13:28:35 +00:00
defer func() {
if nil != conn {
conn.Close()
}
logging.Logger().Infof("disconnected")
2018-04-04 13:50:34 +00:00
crw.ClientStopWg.Done()
2018-04-04 13:28:35 +00:00
}()
logging.Logger().Infof("connected")
var err error
for {
if nil != err {
2018-04-04 14:21:40 +00:00
if IsUnexpectedCloseError(err) || io.EOF == err || io.ErrUnexpectedEOF == err {
2018-04-04 13:50:34 +00:00
crw.DisconnectedChan <- struct{}{}
newConn := <-crw.ReconnectedChan
2018-04-04 13:28:35 +00:00
if nil == newConn {
return
}
conn = newConn
} else {
return
}
}
2018-04-04 14:21:40 +00:00
stopChan := make(chan struct{})
readerDoneChan := make(chan error)
writerDoneChan := make(chan error)
2018-04-04 13:50:34 +00:00
go connReadHandler(crw.ReadwriteHandler, conn, stopChan, readerDoneChan, crw.ReadChan)
go connWriteHandler(crw.ReadwriteHandler, conn, stopChan, writerDoneChan, crw.WriteChan)
2018-04-04 13:28:35 +00:00
select {
case err = <-readerDoneChan:
close(stopChan)
<-writerDoneChan
case err = <-writerDoneChan:
close(stopChan)
<-readerDoneChan
2018-04-04 13:50:34 +00:00
case <-crw.ClientStopChan:
2018-04-04 13:28:35 +00:00
close(stopChan)
<-readerDoneChan
<-writerDoneChan
return
}
}
}