server-go/client-readwriter.go
crusader 899fc53ded ing
2018-04-05 01:51:34 +09:00

71 lines
1.4 KiB
Go

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