Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

httpflv使用问题 #70

Open
zxs943023403 opened this issue Apr 23, 2023 · 1 comment
Open

httpflv使用问题 #70

zxs943023403 opened this issue Apr 23, 2023 · 1 comment

Comments

@zxs943023403
Copy link

使用httpflv进行播放的时候,通过<-request.Context().Done()方法获取到客户端在播放结束前关闭了当前链接,此时http处理方法返回会导致panic
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x1110196]

goroutine 12 [running]:
bufio.(*Writer).Flush(0xc00007ea40)
/sdk/go1.17/src/bufio/bufio.go:607 +0x56
bufio.(*Writer).Write(0xc00007ea40, {0xc00025e000, 0xc00025e000, 0xc000028d75})
/sdk/go1.17/src/bufio/bufio.go:643 +0xd8
net/http.(*response).write(0xc000152380, 0x90a, {0xc00025e000, 0x90a, 0xa80}, {0x0, 0x0})
/sdk/go1.17/src/net/http/server.go:1592 +0x21e
net/http.(*response).Write(0x0, {0xc00025e000, 0x1052306, 0x1064be0})
/sdk/go1.17/src/net/http/server.go:1550 +0x30
github.com/yapingcat/gomedia/go-flv.(*FlvWriter).writeVideo(0xc00000ec18, {0xc000233b00, 0xc000257d80, 0x10601ce}, 0x87b20a44, 0xc7c)
/Desktop/gopath/pkg/mod/github.com/yapingcat/[email protected]/go-flv/flv-file.go:373 +0x9f
github.com/yapingcat/gomedia/go-flv.(*FlvWriter).WriteH264(0x989680, {0xc000233b00, 0xc000544230, 0x0}, 0x4bfb, 0x4bfb)
/Desktop/gopath/pkg/mod/github.com/yapingcat/[email protected]/go-flv/flv-file.go:354 +0x155
是否可以在flvwriter增加一个writer是否已关闭的判断,或者手动关闭的方法?

@yapingcat
Copy link
Owner

yapingcat commented Apr 23, 2023

目前gomedia不管理网络连接,连接交由调用方来管理

针对这个问题,可以把http.ResponseWriter封装一下,在封装的接口里面实现上述的逻辑判断
类似下面这个简单实现

type HttpWriterWrapper struct {
	closed    chan struct{}
	w         http.ResponseWriter
	sendChan  chan []byte
	die       chan struct{}
	lastError error
	once      sync.Once
}

func NewHttpWriterWrapper(w http.ResponseWriter, closed chan struct{}) *HttpWriterWrapper {
	return &HttpWriterWrapper{
		closed:   closed,
		w:        w,
		sendChan: make(chan []byte, 100),
		die:      make(chan struct{}),
	}
}

func (w *HttpWriterWrapper) Start() {
	go w.writeImpl()
}

func (w *HttpWriterWrapper) Stop() {
	w.once.Do(func() {
		close(w.closed)
	})
}

func (w *HttpWriterWrapper) Write(b []byte) (int, error) {
	if w.lastError != nil {
		return 0, w.lastError
	}
	w.sendChan <- b
	return len(b), nil
}

func (w *HttpWriterWrapper) writeImpl() {
	for {
		select {
		case <-w.closed:
			// reset connection by client
			// stop send
			// release some resource
			w.lastError = io.EOF
			return
		case b := <-w.sendChan:
			_, w.lastError = w.w.Write(b)
		case <-w.die:
			w.lastError = errors.New("closed by custom")
			return
		}
	}
}

//使用的时候
write_wrapper := NewHttpWriterWrapper(w,r.Context().Done())
writer := flv.CreateFlvWriter(write_wrapper)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants