Почему клиенты, читающие мое видео через http.ServeContent, продолжают закрывать соединение? - PullRequest
0 голосов
/ 15 апреля 2019

В настоящее время я работаю над небольшим проектом для передачи видео в браузер или другие медиа-клиенты через 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
}

Я пытался отлаживать уже несколько дней и не могу понять причину. Я сравнивал байты, которые я обслуживаю, с настоящим файлом, и, похоже, с данными все в порядке.

Есть идеи, что может быть не так?

1 Ответ

1 голос
/ 15 апреля 2019

Нет ничего плохого. Нет ничего, что требовало бы от клиента не отключаться, пока сервер не отправит все данные. Очень часто, особенно для файлов mp4, клиент выполняет стандартный http-запрос, а затем отменяет его после получения заголовков.

Я подозреваю, что видео воспроизводится не так, как вы ожидаете? Если это так, убедитесь, что ваш сервер реализует запросы диапазона http.

...