mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-10-04 20:22:41 +08:00
101 lines
2.3 KiB
Go
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)
|
|
}
|