71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
|
package socket
|
||
|
|
||
|
import (
|
||
|
"io"
|
||
|
"sync"
|
||
|
|
||
|
olog "git.loafle.net/overflow/log-go"
|
||
|
)
|
||
|
|
||
|
type ClientReadWriter struct {
|
||
|
ReadwriteHandler ReadWriteHandler
|
||
|
ReadChan chan<- SocketMessage
|
||
|
WriteChan <-chan SocketMessage
|
||
|
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()
|
||
|
}
|
||
|
olog.Logger().Info("disconnected")
|
||
|
crw.ClientStopWg.Done()
|
||
|
}()
|
||
|
|
||
|
olog.Logger().Info("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
|
||
|
}
|
||
|
}
|
||
|
}
|