58 lines
1.3 KiB
Go
58 lines
1.3 KiB
Go
package networking
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
|
|
type AsyncReader struct {
|
|
BufSize int
|
|
stream io.ReadCloser
|
|
dataChan chan []byte
|
|
stopFlag bool
|
|
}
|
|
|
|
// NewListen starts listening for a single connection on the given address.
|
|
// This method blocks until this is done.
|
|
func NewAsyncReader(reader io.ReadCloser) *AsyncReader {
|
|
return &AsyncReader{
|
|
BufSize: defaultBufSize,
|
|
stream: reader,
|
|
stopFlag: false,
|
|
}
|
|
}
|
|
|
|
// RecvChan returns a read-only channel of byte slices and starts
|
|
// receiving and pushing data into it asynchronously.
|
|
// The channel is closed when the sender closes the connection.
|
|
// Use this to read bytes from the network connection.
|
|
// The data read is owned by the reader, it is thread-safe to modify.
|
|
func (ar *AsyncReader) RecvChan() <-chan []byte {
|
|
ar.dataChan = make(chan []byte)
|
|
go ar.recvLoop()
|
|
return ar.dataChan
|
|
}
|
|
|
|
func (ar *AsyncReader) recvLoop() {
|
|
buf := make([]byte, ar.BufSize)
|
|
for !ar.stopFlag {
|
|
n, err := ar.stream.Read(buf)
|
|
if err != nil {
|
|
ar.stopFlag = true
|
|
}
|
|
if n > 0 {
|
|
// the underlying memory of the buffer
|
|
// must be copied for thread safety
|
|
sendBuf := make([]byte, n)
|
|
copy(sendBuf, buf)
|
|
ar.dataChan <- sendBuf
|
|
}
|
|
}
|
|
close(ar.dataChan)
|
|
}
|
|
|
|
func (ar *AsyncReader) Close() {
|
|
ar.stopFlag = true
|
|
ar.stream.Close()
|
|
}
|