В настоящее время я работаю над небольшим проектом для передачи видео в браузер или другие медиа-клиенты через http.ServeContent. Я реализовал свой собственный ReadSeeker, который выглядит следующим образом:
//the seek is not fully working yet but works fine for the initial two calls that is being called internally from http to decide the file size.
func (c *Client) Seek(offset int64, whence int) (t int64, e error) {
switch whence {
case 0:
t = offset
case 1:
t = c.seek + offset
case 2:
t = c.SelectedFile().Length + offset
}
if c.seek != t {
//TODO
c.seek = t
}
return
}
func (c *Client) Read(p []byte) (n int, err error) {
if c.done {
return 0, io.EOF
}
for {
result := <-c.Results
if result.piece == nil {
return 0, io.EOF
}
for i, b := range result.bytes {
index := int64(i)
if index < 0 || index > c.SelectedFile().Length {
continue
}
n++
p[index] = b
}
return
}
}
Все работает отлично и отлично, если я, например, использую curl для извлечения данных, например, данные продолжают передаваться в потоке (1024 байта на чтение). Однако, как только я использую браузер или даже VLC, после 5-10 операций чтения http writer.Write () возвращает ошибку EPIPE, и соединение разрывается. Похоже, что ошибка происходит непосредственно от dst.Write (buf [0: nr]) внутри io.go:
...
func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
...
for {
nr, er := src.Read(buf)
if nr > 0 {
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = ErrShortWrite
break
}
}
if er != nil {
if er != EOF {
err = er
}
break
}
}
return written, err
}
Я пытался отлаживать уже несколько дней и не могу понять причину. Я сравнивал байты, которые я обслуживаю, с настоящим файлом, и, похоже, с данными все в порядке.
Есть идеи, что может быть не так?