Files
monibuca/puller.go
2024-08-08 19:42:14 +08:00

101 lines
2.3 KiB
Go

package m7s
import (
"context"
"m7s.live/m7s/v5/pkg"
"m7s.live/m7s/v5/pkg/config"
"time"
)
type Connection struct {
pkg.Task
Plugin *Plugin
StreamPath string // 对应本地流
RemoteURL string // 远程服务器地址(用于推拉)
ReConnectCount int //重连次数
ConnectProxy string // 连接代理
MetaData any
}
func (client *Connection) reconnect(count int) (ok bool) {
ok = count == -1 || client.ReConnectCount <= count
client.ReConnectCount++
return
}
type Puller = func(*PullContext) error
func createPullContext(p *Plugin, streamPath string, url string, options ...any) (pullCtx *PullContext) {
pullCtx = &PullContext{Pull: p.config.Pull}
pullCtx.ID = p.Server.pullTM.GetID()
pullCtx.Plugin = p
pullCtx.ConnectProxy = p.config.Pull.Proxy
pullCtx.RemoteURL = url
publishConfig := p.config.Publish
publishConfig.PublishTimeout = 0
pullCtx.StreamPath = streamPath
pullCtx.PublishOptions = []any{publishConfig}
var ctx = p.Context
for _, option := range options {
switch v := option.(type) {
case context.Context:
ctx = v
default:
pullCtx.PublishOptions = append(pullCtx.PublishOptions, option)
}
}
p.Init(ctx, p.Logger.With("pullURL", url, "streamPath", streamPath))
pullCtx.PublishOptions = append(pullCtx.PublishOptions, pullCtx.Context)
return
}
type PullContext struct {
Connection
Publisher *Publisher
PublishOptions []any
config.Pull
}
func (p *PullContext) GetKey() string {
return p.StreamPath
}
func (p *PullContext) Run(puller Puller) {
var err error
for p.reconnect(p.RePull) {
if p.Publisher != nil {
if time.Since(p.Publisher.StartTime) < 5*time.Second {
time.Sleep(5 * time.Second)
}
p.Warn("retry", "count", p.ReConnectCount, "total", p.RePull)
}
if p.Publisher, err = p.Plugin.Publish(p.StreamPath, p.PublishOptions...); err != nil {
p.Error("pull publish failed", "error", err)
break
}
err = puller(p)
p.Publisher.Stop(err)
if p.IsStopped() {
return
}
p.Error("pull interrupt", "error", err)
}
if err == nil {
err = pkg.ErrRetryRunOut
}
p.Stop(err)
}
func (p *PullContext) Start() (err error) {
s := p.Plugin.Server
if _, ok := s.Pulls.Get(p.GetKey()); ok {
return pkg.ErrStreamExist
}
s.Pulls.Add(p)
return
}
func (p *PullContext) Dispose() {
p.Plugin.Server.Pulls.Remove(p)
}