mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-12-24 13:48:04 +08:00
Compare commits
12 Commits
v5.0.1
...
v5.0.2-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd1a398ca2 | ||
|
|
50cdfad931 | ||
|
|
6df793a8fb | ||
|
|
74c948d0c3 | ||
|
|
80ad1044e3 | ||
|
|
47884b6880 | ||
|
|
a38ddd68aa | ||
|
|
a2bc3d94c1 | ||
|
|
8d6bcc7b1b | ||
|
|
f475419b7b | ||
|
|
b8772f62c1 | ||
|
|
962f2450e5 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -19,3 +19,4 @@ __debug*
|
||||
example/default/*
|
||||
!example/default/main.go
|
||||
!example/default/config.yaml
|
||||
shutdown.sh
|
||||
@@ -11,6 +11,9 @@ COPY monibuca_arm64 ./monibuca_arm64
|
||||
|
||||
COPY admin.zip ./admin.zip
|
||||
|
||||
# Install tcpdump
|
||||
RUN apt-get update && apt-get install -y tcpdump && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy the configuration file from the build context
|
||||
COPY example/default/config.yaml /etc/monibuca/config.yaml
|
||||
|
||||
|
||||
209
api.go
209
api.go
@@ -79,7 +79,7 @@ func (s *Server) DisabledPlugins(ctx context.Context, _ *emptypb.Empty) (res *pb
|
||||
|
||||
// /api/stream/annexb/{streamPath}
|
||||
func (s *Server) api_Stream_AnnexB_(rw http.ResponseWriter, r *http.Request) {
|
||||
publisher, ok := s.Streams.Get(r.PathValue("streamPath"))
|
||||
publisher, ok := s.Streams.SafeGet(r.PathValue("streamPath"))
|
||||
if !ok || publisher.VideoTrack.AVTrack == nil {
|
||||
http.Error(rw, pkg.ErrNotFound.Error(), http.StatusNotFound)
|
||||
return
|
||||
@@ -195,18 +195,15 @@ func (s *Server) StreamInfo(ctx context.Context, req *pb.StreamSnapRequest) (res
|
||||
}
|
||||
return nil
|
||||
})
|
||||
s.Streams.Call(func() error {
|
||||
if pub, ok := s.Streams.Get(req.StreamPath); ok {
|
||||
res, err = s.getStreamInfo(pub)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res.Data.Recording = recordings
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
if pub, ok := s.Streams.SafeGet(req.StreamPath); ok {
|
||||
res, err = s.getStreamInfo(pub)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return nil
|
||||
})
|
||||
res.Data.Recording = recordings
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -324,50 +321,47 @@ func (s *Server) GetSubscribers(context.Context, *pb.SubscribersRequest) (res *p
|
||||
return
|
||||
}
|
||||
func (s *Server) AudioTrackSnap(_ context.Context, req *pb.StreamSnapRequest) (res *pb.TrackSnapShotResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if pub, ok := s.Streams.Get(req.StreamPath); ok && pub.HasAudioTrack() {
|
||||
data := &pb.TrackSnapShotData{}
|
||||
if pub.AudioTrack.Allocator != nil {
|
||||
for _, memlist := range pub.AudioTrack.Allocator.GetChildren() {
|
||||
var list []*pb.MemoryBlock
|
||||
for _, block := range memlist.GetBlocks() {
|
||||
list = append(list, &pb.MemoryBlock{
|
||||
S: uint32(block.Start),
|
||||
E: uint32(block.End),
|
||||
})
|
||||
}
|
||||
data.Memory = append(data.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
||||
if pub, ok := s.Streams.SafeGet(req.StreamPath); ok && pub.HasAudioTrack() {
|
||||
data := &pb.TrackSnapShotData{}
|
||||
if pub.AudioTrack.Allocator != nil {
|
||||
for _, memlist := range pub.AudioTrack.Allocator.GetChildren() {
|
||||
var list []*pb.MemoryBlock
|
||||
for _, block := range memlist.GetBlocks() {
|
||||
list = append(list, &pb.MemoryBlock{
|
||||
S: uint32(block.Start),
|
||||
E: uint32(block.End),
|
||||
})
|
||||
}
|
||||
data.Memory = append(data.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
||||
}
|
||||
pub.AudioTrack.Ring.Do(func(v *pkg.AVFrame) {
|
||||
if len(v.Wraps) > 0 {
|
||||
var snap pb.TrackSnapShot
|
||||
snap.Sequence = v.Sequence
|
||||
snap.Timestamp = uint32(v.Timestamp / time.Millisecond)
|
||||
snap.WriteTime = timestamppb.New(v.WriteTime)
|
||||
snap.Wrap = make([]*pb.Wrap, len(v.Wraps))
|
||||
snap.KeyFrame = v.IDR
|
||||
data.RingDataSize += uint32(v.Wraps[0].GetSize())
|
||||
for i, wrap := range v.Wraps {
|
||||
snap.Wrap[i] = &pb.Wrap{
|
||||
Timestamp: uint32(wrap.GetTimestamp() / time.Millisecond),
|
||||
Size: uint32(wrap.GetSize()),
|
||||
Data: wrap.String(),
|
||||
}
|
||||
}
|
||||
data.Ring = append(data.Ring, &snap)
|
||||
}
|
||||
})
|
||||
res = &pb.TrackSnapShotResponse{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
Data: data,
|
||||
}
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
}
|
||||
return nil
|
||||
})
|
||||
pub.AudioTrack.Ring.Do(func(v *pkg.AVFrame) {
|
||||
if len(v.Wraps) > 0 {
|
||||
var snap pb.TrackSnapShot
|
||||
snap.Sequence = v.Sequence
|
||||
snap.Timestamp = uint32(v.Timestamp / time.Millisecond)
|
||||
snap.WriteTime = timestamppb.New(v.WriteTime)
|
||||
snap.Wrap = make([]*pb.Wrap, len(v.Wraps))
|
||||
snap.KeyFrame = v.IDR
|
||||
data.RingDataSize += uint32(v.Wraps[0].GetSize())
|
||||
for i, wrap := range v.Wraps {
|
||||
snap.Wrap[i] = &pb.Wrap{
|
||||
Timestamp: uint32(wrap.GetTimestamp() / time.Millisecond),
|
||||
Size: uint32(wrap.GetSize()),
|
||||
Data: wrap.String(),
|
||||
}
|
||||
}
|
||||
data.Ring = append(data.Ring, &snap)
|
||||
}
|
||||
})
|
||||
res = &pb.TrackSnapShotResponse{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
Data: data,
|
||||
}
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
func (s *Server) api_VideoTrack_SSE(rw http.ResponseWriter, r *http.Request) {
|
||||
@@ -437,50 +431,47 @@ func (s *Server) api_AudioTrack_SSE(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (s *Server) VideoTrackSnap(ctx context.Context, req *pb.StreamSnapRequest) (res *pb.TrackSnapShotResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if pub, ok := s.Streams.Get(req.StreamPath); ok && pub.HasVideoTrack() {
|
||||
data := &pb.TrackSnapShotData{}
|
||||
if pub.VideoTrack.Allocator != nil {
|
||||
for _, memlist := range pub.VideoTrack.Allocator.GetChildren() {
|
||||
var list []*pb.MemoryBlock
|
||||
for _, block := range memlist.GetBlocks() {
|
||||
list = append(list, &pb.MemoryBlock{
|
||||
S: uint32(block.Start),
|
||||
E: uint32(block.End),
|
||||
})
|
||||
}
|
||||
data.Memory = append(data.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
||||
if pub, ok := s.Streams.SafeGet(req.StreamPath); ok && pub.HasVideoTrack() {
|
||||
data := &pb.TrackSnapShotData{}
|
||||
if pub.VideoTrack.Allocator != nil {
|
||||
for _, memlist := range pub.VideoTrack.Allocator.GetChildren() {
|
||||
var list []*pb.MemoryBlock
|
||||
for _, block := range memlist.GetBlocks() {
|
||||
list = append(list, &pb.MemoryBlock{
|
||||
S: uint32(block.Start),
|
||||
E: uint32(block.End),
|
||||
})
|
||||
}
|
||||
data.Memory = append(data.Memory, &pb.MemoryBlockGroup{List: list, Size: uint32(memlist.Size)})
|
||||
}
|
||||
pub.VideoTrack.Ring.Do(func(v *pkg.AVFrame) {
|
||||
if len(v.Wraps) > 0 {
|
||||
var snap pb.TrackSnapShot
|
||||
snap.Sequence = v.Sequence
|
||||
snap.Timestamp = uint32(v.Timestamp / time.Millisecond)
|
||||
snap.WriteTime = timestamppb.New(v.WriteTime)
|
||||
snap.Wrap = make([]*pb.Wrap, len(v.Wraps))
|
||||
snap.KeyFrame = v.IDR
|
||||
data.RingDataSize += uint32(v.Wraps[0].GetSize())
|
||||
for i, wrap := range v.Wraps {
|
||||
snap.Wrap[i] = &pb.Wrap{
|
||||
Timestamp: uint32(wrap.GetTimestamp() / time.Millisecond),
|
||||
Size: uint32(wrap.GetSize()),
|
||||
Data: wrap.String(),
|
||||
}
|
||||
}
|
||||
data.Ring = append(data.Ring, &snap)
|
||||
}
|
||||
})
|
||||
res = &pb.TrackSnapShotResponse{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
Data: data,
|
||||
}
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
}
|
||||
return nil
|
||||
})
|
||||
pub.VideoTrack.Ring.Do(func(v *pkg.AVFrame) {
|
||||
if len(v.Wraps) > 0 {
|
||||
var snap pb.TrackSnapShot
|
||||
snap.Sequence = v.Sequence
|
||||
snap.Timestamp = uint32(v.Timestamp / time.Millisecond)
|
||||
snap.WriteTime = timestamppb.New(v.WriteTime)
|
||||
snap.Wrap = make([]*pb.Wrap, len(v.Wraps))
|
||||
snap.KeyFrame = v.IDR
|
||||
data.RingDataSize += uint32(v.Wraps[0].GetSize())
|
||||
for i, wrap := range v.Wraps {
|
||||
snap.Wrap[i] = &pb.Wrap{
|
||||
Timestamp: uint32(wrap.GetTimestamp() / time.Millisecond),
|
||||
Size: uint32(wrap.GetSize()),
|
||||
Data: wrap.String(),
|
||||
}
|
||||
}
|
||||
data.Ring = append(data.Ring, &snap)
|
||||
}
|
||||
})
|
||||
res = &pb.TrackSnapShotResponse{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
Data: data,
|
||||
}
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -500,7 +491,7 @@ func (s *Server) Shutdown(ctx context.Context, req *pb.RequestWithId) (res *pb.S
|
||||
func (s *Server) ChangeSubscribe(ctx context.Context, req *pb.ChangeSubscribeRequest) (res *pb.SuccessResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if subscriber, ok := s.Subscribers.Get(req.Id); ok {
|
||||
if pub, ok := s.Streams.Get(req.StreamPath); ok {
|
||||
if pub, ok := s.Streams.SafeGet(req.StreamPath); ok {
|
||||
subscriber.Publisher.RemoveSubscriber(subscriber)
|
||||
subscriber.StreamPath = req.StreamPath
|
||||
pub.AddSubscriber(subscriber)
|
||||
@@ -527,7 +518,7 @@ func (s *Server) StopSubscribe(ctx context.Context, req *pb.RequestWithId) (res
|
||||
|
||||
func (s *Server) PauseStream(ctx context.Context, req *pb.StreamSnapRequest) (res *pb.SuccessResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if s, ok := s.Streams.Get(req.StreamPath); ok {
|
||||
if s, ok := s.Streams.SafeGet(req.StreamPath); ok {
|
||||
s.Pause()
|
||||
}
|
||||
return nil
|
||||
@@ -537,7 +528,7 @@ func (s *Server) PauseStream(ctx context.Context, req *pb.StreamSnapRequest) (re
|
||||
|
||||
func (s *Server) ResumeStream(ctx context.Context, req *pb.StreamSnapRequest) (res *pb.SuccessResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if s, ok := s.Streams.Get(req.StreamPath); ok {
|
||||
if s, ok := s.Streams.SafeGet(req.StreamPath); ok {
|
||||
s.Resume()
|
||||
}
|
||||
return nil
|
||||
@@ -547,7 +538,7 @@ func (s *Server) ResumeStream(ctx context.Context, req *pb.StreamSnapRequest) (r
|
||||
|
||||
func (s *Server) SetStreamSpeed(ctx context.Context, req *pb.SetStreamSpeedRequest) (res *pb.SuccessResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if s, ok := s.Streams.Get(req.StreamPath); ok {
|
||||
if s, ok := s.Streams.SafeGet(req.StreamPath); ok {
|
||||
s.Speed = float64(req.Speed)
|
||||
s.Scale = float64(req.Speed)
|
||||
s.Info("set stream speed", "speed", req.Speed)
|
||||
@@ -559,7 +550,7 @@ func (s *Server) SetStreamSpeed(ctx context.Context, req *pb.SetStreamSpeedReque
|
||||
|
||||
func (s *Server) SeekStream(ctx context.Context, req *pb.SeekStreamRequest) (res *pb.SuccessResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if s, ok := s.Streams.Get(req.StreamPath); ok {
|
||||
if s, ok := s.Streams.SafeGet(req.StreamPath); ok {
|
||||
s.Seek(time.Unix(int64(req.TimeStamp), 0))
|
||||
}
|
||||
return nil
|
||||
@@ -569,7 +560,7 @@ func (s *Server) SeekStream(ctx context.Context, req *pb.SeekStreamRequest) (res
|
||||
|
||||
func (s *Server) StopPublish(ctx context.Context, req *pb.StreamSnapRequest) (res *pb.SuccessResponse, err error) {
|
||||
s.Streams.Call(func() error {
|
||||
if s, ok := s.Streams.Get(req.StreamPath); ok {
|
||||
if s, ok := s.Streams.SafeGet(req.StreamPath); ok {
|
||||
s.Stop(task.ErrStopByUser)
|
||||
}
|
||||
return nil
|
||||
@@ -632,24 +623,18 @@ func (s *Server) Api_Summary_SSE(rw http.ResponseWriter, r *http.Request) {
|
||||
func (s *Server) Api_Stream_Position_SSE(rw http.ResponseWriter, r *http.Request) {
|
||||
streamPath := r.URL.Query().Get("streamPath")
|
||||
util.ReturnFetchValue(func() (t time.Time) {
|
||||
s.Streams.Call(func() error {
|
||||
if pub, ok := s.Streams.Get(streamPath); ok {
|
||||
t = pub.GetPosition()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if pub, ok := s.Streams.SafeGet(streamPath); ok {
|
||||
t = pub.GetPosition()
|
||||
}
|
||||
return
|
||||
}, rw, r)
|
||||
}
|
||||
|
||||
// func (s *Server) Api_Vod_Position(rw http.ResponseWriter, r *http.Request) {
|
||||
// streamPath := r.URL.Query().Get("streamPath")
|
||||
// s.Streams.Call(func() error {
|
||||
// if pub, ok := s.Streams.Get(streamPath); ok {
|
||||
// t = pub.GetPosition()
|
||||
// }
|
||||
// return nil
|
||||
// })
|
||||
// if pub, ok := s.Streams.SafeGet(streamPath); ok {
|
||||
// t = pub.GetPosition()
|
||||
// }
|
||||
// }
|
||||
|
||||
func (s *Server) Summary(context.Context, *emptypb.Empty) (res *pb.SummaryResponse, err error) {
|
||||
|
||||
@@ -7,4 +7,9 @@ rtsp:
|
||||
mp4:
|
||||
enable: true
|
||||
pull:
|
||||
live/test: /Users/dexter/Movies/test.mp4
|
||||
live/test: /Users/dexter/Movies/test.mp4
|
||||
rtmp:
|
||||
enable: true
|
||||
|
||||
debug:
|
||||
enable: true
|
||||
|
||||
13
example/8081/default.yaml
Normal file
13
example/8081/default.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
global:
|
||||
# loglevel: debug
|
||||
http:
|
||||
listenaddr: :8081
|
||||
listenaddrtls: :8555
|
||||
tcp:
|
||||
listenaddr: :50052
|
||||
rtsp:
|
||||
enable: false
|
||||
rtmp:
|
||||
tcp: :1936
|
||||
webrtc:
|
||||
enable: false
|
||||
@@ -16,11 +16,19 @@ const (
|
||||
RelayModeRelay = "relay"
|
||||
RelayModeMix = "mix"
|
||||
|
||||
HookOnPublish HookType = "publish"
|
||||
HookOnSubscribe HookType = "subscribe"
|
||||
HookOnPublishEnd HookType = "publish_end"
|
||||
HookOnSubscribeEnd HookType = "subscribe_end"
|
||||
HookOnServerKeepAlive HookType = "server_keep_alive"
|
||||
HookOnPublishStart HookType = "publish_start"
|
||||
HookOnPublishEnd HookType = "publish_end"
|
||||
HookOnSubscribeStart HookType = "subscribe_start"
|
||||
HookOnSubscribeEnd HookType = "subscribe_end"
|
||||
HookOnPullStart HookType = "pull_start"
|
||||
HookOnPullEnd HookType = "pull_end"
|
||||
HookOnPushStart HookType = "push_start"
|
||||
HookOnPushEnd HookType = "push_end"
|
||||
HookOnRecordStart HookType = "record_start"
|
||||
HookOnRecordEnd HookType = "record_end"
|
||||
HookOnTransformStart HookType = "transform_start"
|
||||
HookOnTransformEnd HookType = "transform_end"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -99,13 +107,13 @@ type (
|
||||
Transform map[Regexp]Transform
|
||||
}
|
||||
Webhook struct {
|
||||
URL string `yaml:"url" json:"url"` // Webhook 地址
|
||||
Method string `yaml:"method" json:"method" default:"POST"` // HTTP 方法
|
||||
Headers map[string]string `yaml:"headers" json:"headers"` // 自定义请求头
|
||||
TimeoutSeconds int `yaml:"timeout" json:"timeout" default:"5"` // 超时时间(秒)
|
||||
RetryTimes int `yaml:"retry" json:"retry" default:"3"` // 重试次数
|
||||
RetryInterval time.Duration `yaml:"retryInterval" json:"retryInterval" default:"1s"` // 重试间隔
|
||||
Interval int `yaml:"interval" json:"interval" default:"60"` // 保活间隔(秒)
|
||||
URL string // Webhook 地址
|
||||
Method string `default:"POST"` // HTTP 方法
|
||||
Headers map[string]string // 自定义请求头
|
||||
TimeoutSeconds int `default:"5"` // 超时时间(秒)
|
||||
RetryTimes int `default:"3"` // 重试次数
|
||||
RetryInterval time.Duration `default:"1s"` // 重试间隔
|
||||
Interval int `default:"60"` // 保活间隔(秒)
|
||||
}
|
||||
Common struct {
|
||||
PublicIP string
|
||||
|
||||
@@ -32,14 +32,15 @@ func GetNextTaskID() uint32 {
|
||||
// Job include tasks
|
||||
type Job struct {
|
||||
Task
|
||||
cases []reflect.SelectCase
|
||||
addSub chan ITask
|
||||
children []ITask
|
||||
lazyRun sync.Once
|
||||
eventLoopLock sync.Mutex
|
||||
childrenDisposed chan struct{}
|
||||
childDisposeListeners []func(ITask)
|
||||
blocked ITask
|
||||
cases []reflect.SelectCase
|
||||
addSub chan ITask
|
||||
children []ITask
|
||||
lazyRun sync.Once
|
||||
eventLoopLock sync.Mutex
|
||||
childrenDisposed chan struct{}
|
||||
descendantsDisposeListeners []func(ITask)
|
||||
descendantsStartListeners []func(ITask)
|
||||
blocked ITask
|
||||
}
|
||||
|
||||
func (*Job) GetTaskType() TaskType {
|
||||
@@ -68,12 +69,12 @@ func (mt *Job) waitChildrenDispose() {
|
||||
}
|
||||
}
|
||||
|
||||
func (mt *Job) OnChildDispose(listener func(ITask)) {
|
||||
mt.childDisposeListeners = append(mt.childDisposeListeners, listener)
|
||||
func (mt *Job) OnDescendantsDispose(listener func(ITask)) {
|
||||
mt.descendantsDisposeListeners = append(mt.descendantsDisposeListeners, listener)
|
||||
}
|
||||
|
||||
func (mt *Job) onDescendantsDispose(descendants ITask) {
|
||||
for _, listener := range mt.childDisposeListeners {
|
||||
for _, listener := range mt.descendantsDisposeListeners {
|
||||
listener(descendants)
|
||||
}
|
||||
if mt.parent != nil {
|
||||
@@ -82,11 +83,28 @@ func (mt *Job) onDescendantsDispose(descendants ITask) {
|
||||
}
|
||||
|
||||
func (mt *Job) onChildDispose(child ITask) {
|
||||
if child.getParent() == mt {
|
||||
if child.GetTaskType() != TASK_TYPE_CALL || child.GetOwnerType() != "CallBack" {
|
||||
mt.onDescendantsDispose(child)
|
||||
}
|
||||
child.dispose()
|
||||
if child.GetTaskType() != TASK_TYPE_CALL || child.GetOwnerType() != "CallBack" {
|
||||
mt.onDescendantsDispose(child)
|
||||
}
|
||||
child.dispose()
|
||||
}
|
||||
|
||||
func (mt *Job) OnDescendantsStart(listener func(ITask)) {
|
||||
mt.descendantsStartListeners = append(mt.descendantsStartListeners, listener)
|
||||
}
|
||||
|
||||
func (mt *Job) onDescendantsStart(descendants ITask) {
|
||||
for _, listener := range mt.descendantsStartListeners {
|
||||
listener(descendants)
|
||||
}
|
||||
if mt.parent != nil {
|
||||
mt.parent.onDescendantsStart(descendants)
|
||||
}
|
||||
}
|
||||
|
||||
func (mt *Job) onChildStart(child ITask) {
|
||||
if child.GetTaskType() != TASK_TYPE_CALL || child.GetOwnerType() != "CallBack" {
|
||||
mt.onDescendantsStart(child)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,9 +229,10 @@ func (mt *Job) run() {
|
||||
if rev.IsNil() {
|
||||
return
|
||||
}
|
||||
if mt.blocked = rev.Interface().(ITask); mt.blocked.getParent() != mt || mt.blocked.start() {
|
||||
if mt.blocked = rev.Interface().(ITask); mt.blocked.start() {
|
||||
mt.children = append(mt.children, mt.blocked)
|
||||
mt.cases = append(mt.cases, reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(mt.blocked.GetSignal())})
|
||||
mt.onChildStart(mt.blocked)
|
||||
}
|
||||
} else {
|
||||
taskIndex := chosen - 1
|
||||
@@ -236,6 +255,7 @@ func (mt *Job) run() {
|
||||
if mt.onChildDispose(mt.blocked); mt.blocked.checkRetry(mt.blocked.StopReason()) {
|
||||
if mt.blocked.reset(); mt.blocked.start() {
|
||||
mt.cases[chosen].Chan = reflect.ValueOf(mt.blocked.GetSignal())
|
||||
mt.onChildStart(mt.blocked)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ type (
|
||||
ITask interface {
|
||||
context.Context
|
||||
keepalive() bool
|
||||
getParent() *Job
|
||||
GetParent() ITask
|
||||
GetTask() *Task
|
||||
GetTaskID() uint32
|
||||
@@ -85,7 +84,8 @@ type (
|
||||
getJob() *Job
|
||||
AddTask(ITask, ...any) *Task
|
||||
RangeSubTask(func(yield ITask) bool)
|
||||
OnChildDispose(func(ITask))
|
||||
OnDescendantsDispose(func(ITask))
|
||||
OnDescendantsStart(func(ITask))
|
||||
Blocked() ITask
|
||||
Call(func() error, ...any)
|
||||
Post(func() error, ...any) *Task
|
||||
@@ -178,10 +178,6 @@ func (task *Task) GetTaskPointer() uintptr {
|
||||
return uintptr(unsafe.Pointer(task))
|
||||
}
|
||||
|
||||
func (task *Task) getParent() *Job {
|
||||
return task.parent
|
||||
}
|
||||
|
||||
func (task *Task) GetKey() uint32 {
|
||||
return task.ID
|
||||
}
|
||||
@@ -435,6 +431,10 @@ func (task *Task) ResetRetryCount() {
|
||||
task.retry.RetryCount = 0
|
||||
}
|
||||
|
||||
func (task *Task) GetRetryCount() int {
|
||||
return task.retry.RetryCount
|
||||
}
|
||||
|
||||
func (task *Task) run(handler func() error) {
|
||||
var err error
|
||||
defer func() {
|
||||
|
||||
@@ -142,6 +142,26 @@ func Test_Hooks(t *testing.T) {
|
||||
root.AddTask(&task).WaitStopped()
|
||||
}
|
||||
|
||||
type startFailTask struct {
|
||||
Task
|
||||
}
|
||||
|
||||
func (task *startFailTask) Start() error {
|
||||
return errors.New("start failed")
|
||||
}
|
||||
|
||||
func (task *startFailTask) Dispose() {
|
||||
task.Logger.Info("Dispose")
|
||||
}
|
||||
|
||||
func Test_StartFail(t *testing.T) {
|
||||
var task startFailTask
|
||||
root.AddTask(&task)
|
||||
if err := task.WaitStarted(); err == nil {
|
||||
t.Errorf("expected start to fail")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//type DemoTask struct {
|
||||
// Task
|
||||
|
||||
178
plugin.go
178
plugin.go
@@ -386,13 +386,13 @@ type WebHookTask struct {
|
||||
task.Task
|
||||
plugin *Plugin
|
||||
hookType config.HookType
|
||||
conf *config.Webhook
|
||||
conf config.Webhook
|
||||
data any
|
||||
jsonData []byte
|
||||
}
|
||||
|
||||
func (t *WebHookTask) Start() error {
|
||||
if t.conf == nil || t.conf.URL == "" {
|
||||
if t.conf.URL == "" {
|
||||
return task.ErrTaskComplete
|
||||
}
|
||||
|
||||
@@ -437,11 +437,11 @@ func (t *WebHookTask) Go() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Plugin) SendWebhook(hookType config.HookType, conf config.Webhook, data any) *task.Task {
|
||||
func (p *Plugin) SendWebhook(hookType config.HookType, data any) *task.Task {
|
||||
webhookTask := &WebHookTask{
|
||||
plugin: p,
|
||||
hookType: hookType,
|
||||
conf: &conf,
|
||||
conf: p.config.Hook[hookType],
|
||||
data: data,
|
||||
}
|
||||
return p.AddTask(webhookTask)
|
||||
@@ -560,10 +560,31 @@ func (p *Plugin) PublishWithConfig(ctx context.Context, streamPath string, conf
|
||||
}
|
||||
err = p.Server.Streams.AddTask(publisher, ctx).WaitStarted()
|
||||
if err == nil {
|
||||
publisher.OnDispose(func() {
|
||||
p.sendPublishEndWebhook(publisher)
|
||||
})
|
||||
p.sendPublishWebhook(publisher)
|
||||
if sender := p.getHookSender(config.HookOnPublishEnd); sender != nil {
|
||||
publisher.OnDispose(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnPublishEnd,
|
||||
"streamPath": publisher.StreamPath,
|
||||
"publishId": publisher.ID,
|
||||
"reason": publisher.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnPublishEnd, webhookData)
|
||||
})
|
||||
}
|
||||
if sender := p.getHookSender(config.HookOnPublishStart); sender != nil {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnPublishStart,
|
||||
"streamPath": publisher.StreamPath,
|
||||
"args": publisher.Args,
|
||||
"publishId": publisher.ID,
|
||||
"remoteAddr": publisher.RemoteAddr,
|
||||
"type": publisher.Type,
|
||||
"pluginName": p.Meta.Name,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnPublishStart, webhookData)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -601,10 +622,34 @@ func (p *Plugin) SubscribeWithConfig(ctx context.Context, streamPath string, con
|
||||
}
|
||||
}
|
||||
if err == nil {
|
||||
subscriber.OnDispose(func() {
|
||||
p.sendSubscribeEndWebhook(subscriber)
|
||||
})
|
||||
p.sendSubscribeWebhook(subscriber)
|
||||
if sender := p.getHookSender(config.HookOnSubscribeEnd); sender != nil {
|
||||
subscriber.OnDispose(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnSubscribeEnd,
|
||||
"streamPath": subscriber.StreamPath,
|
||||
"subscriberId": subscriber.ID,
|
||||
"reason": subscriber.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
if subscriber.Publisher != nil {
|
||||
webhookData["publishId"] = subscriber.Publisher.ID
|
||||
}
|
||||
sender(config.HookOnSubscribeEnd, webhookData)
|
||||
})
|
||||
}
|
||||
if sender := p.getHookSender(config.HookOnSubscribeStart); sender != nil {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnSubscribeStart,
|
||||
"streamPath": subscriber.StreamPath,
|
||||
"publishId": subscriber.Publisher.ID,
|
||||
"subscriberId": subscriber.ID,
|
||||
"remoteAddr": subscriber.RemoteAddr,
|
||||
"type": subscriber.Type,
|
||||
"args": subscriber.Args,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnSubscribeStart, webhookData)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -715,90 +760,17 @@ func (p *Plugin) handle(pattern string, handler http.Handler) {
|
||||
p.Server.apiList = append(p.Server.apiList, pattern)
|
||||
}
|
||||
|
||||
func (p *Plugin) sendPublishWebhook(pub *Publisher) {
|
||||
if p.config.Hook == nil {
|
||||
return
|
||||
func (p *Plugin) getHookSender(hookType config.HookType) (sender func(hookType config.HookType, data any) *task.Task) {
|
||||
if p.config.Hook != nil {
|
||||
if _, ok := p.config.Hook[hookType]; ok {
|
||||
sender = p.SendWebhook
|
||||
} else if p.Server.config.Hook != nil {
|
||||
if _, ok := p.Server.config.Hook[hookType]; ok {
|
||||
sender = p.Server.SendWebhook
|
||||
}
|
||||
}
|
||||
}
|
||||
webhookData := map[string]interface{}{
|
||||
"event": "publish",
|
||||
"streamPath": pub.StreamPath,
|
||||
"args": pub.Args,
|
||||
"publishId": pub.ID,
|
||||
"remoteAddr": pub.RemoteAddr,
|
||||
"type": pub.Type,
|
||||
"pluginName": p.Meta.Name,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
p.SendWebhook(config.HookOnPublish, p.config.Hook[config.HookOnPublish], webhookData)
|
||||
if p.Server.config.Hook == nil {
|
||||
return
|
||||
}
|
||||
p.Server.SendWebhook(config.HookOnPublish, p.Server.config.Hook[config.HookOnPublish], webhookData)
|
||||
}
|
||||
|
||||
func (p *Plugin) sendPublishEndWebhook(pub *Publisher) {
|
||||
if p.config.Hook == nil {
|
||||
return
|
||||
}
|
||||
webhookData := map[string]interface{}{
|
||||
"event": "publish_end",
|
||||
"streamPath": pub.StreamPath,
|
||||
"publishId": pub.ID,
|
||||
"reason": pub.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
p.SendWebhook(config.HookOnPublishEnd, p.config.Hook[config.HookOnPublishEnd], webhookData)
|
||||
}
|
||||
|
||||
func (p *Plugin) sendSubscribeWebhook(sub *Subscriber) {
|
||||
if p.config.Hook == nil {
|
||||
return
|
||||
}
|
||||
webhookData := map[string]interface{}{
|
||||
"event": "subscribe",
|
||||
"streamPath": sub.StreamPath,
|
||||
"publishId": sub.Publisher.ID,
|
||||
"subscriberId": sub.ID,
|
||||
"remoteAddr": sub.RemoteAddr,
|
||||
"type": sub.Type,
|
||||
"args": sub.Args,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
p.SendWebhook(config.HookOnSubscribe, p.config.Hook[config.HookOnSubscribe], webhookData)
|
||||
}
|
||||
|
||||
func (p *Plugin) sendSubscribeEndWebhook(sub *Subscriber) {
|
||||
if p.config.Hook == nil {
|
||||
return
|
||||
}
|
||||
webhookData := map[string]interface{}{
|
||||
"event": "subscribe_end",
|
||||
"streamPath": sub.StreamPath,
|
||||
"subscriberId": sub.ID,
|
||||
"reason": sub.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
if sub.Publisher != nil {
|
||||
webhookData["publishId"] = sub.Publisher.ID
|
||||
}
|
||||
p.SendWebhook(config.HookOnSubscribeEnd, p.config.Hook[config.HookOnSubscribeEnd], webhookData)
|
||||
}
|
||||
|
||||
func (p *Plugin) sendServerKeepAliveWebhook() {
|
||||
if p.config.Hook == nil {
|
||||
return
|
||||
}
|
||||
s := p.Server
|
||||
webhookData := map[string]interface{}{
|
||||
"event": "server_keep_alive",
|
||||
"timestamp": time.Now().Unix(),
|
||||
"streams": s.Streams.Length,
|
||||
"subscribers": s.Subscribers.Length,
|
||||
"publisherCount": s.Streams.Length,
|
||||
"subscriberCount": s.Subscribers.Length,
|
||||
"uptime": time.Since(s.StartTime).Seconds(),
|
||||
}
|
||||
p.SendWebhook(config.HookOnServerKeepAlive, p.config.Hook[config.HookOnServerKeepAlive], webhookData)
|
||||
return
|
||||
}
|
||||
|
||||
type ServerKeepAliveTask struct {
|
||||
@@ -811,5 +783,19 @@ func (t *ServerKeepAliveTask) GetTickInterval() time.Duration {
|
||||
}
|
||||
|
||||
func (t *ServerKeepAliveTask) Tick(now any) {
|
||||
t.plugin.sendServerKeepAliveWebhook()
|
||||
sender := t.plugin.getHookSender(config.HookOnServerKeepAlive)
|
||||
if sender == nil {
|
||||
return
|
||||
}
|
||||
s := t.plugin.Server
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnServerKeepAlive,
|
||||
"timestamp": time.Now().Unix(),
|
||||
"streams": s.Streams.Length,
|
||||
"subscribers": s.Subscribers.Length,
|
||||
"publisherCount": s.Streams.Length,
|
||||
"subscriberCount": s.Subscribers.Length,
|
||||
"uptime": time.Since(s.StartTime).Seconds(),
|
||||
}
|
||||
sender(config.HookOnServerKeepAlive, webhookData)
|
||||
}
|
||||
|
||||
211
plugin/crontab/api.go
Normal file
211
plugin/crontab/api.go
Normal file
@@ -0,0 +1,211 @@
|
||||
package plugin_crontab
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
cronpb "m7s.live/v5/plugin/crontab/pb"
|
||||
"m7s.live/v5/plugin/crontab/pkg"
|
||||
)
|
||||
|
||||
func (ct *CrontabPlugin) List(ctx context.Context, req *cronpb.ReqPlanList) (*cronpb.PlanResponseList, error) {
|
||||
if req.PageNum < 1 {
|
||||
req.PageNum = 1
|
||||
}
|
||||
if req.PageSize < 1 {
|
||||
req.PageSize = 10
|
||||
}
|
||||
|
||||
var total int64
|
||||
var plans []pkg.RecordPlan
|
||||
|
||||
query := ct.DB.Model(&pkg.RecordPlan{})
|
||||
|
||||
result := query.Count(&total)
|
||||
if result.Error != nil {
|
||||
return &cronpb.PlanResponseList{
|
||||
Code: 500,
|
||||
Message: result.Error.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
offset := (req.PageNum - 1) * req.PageSize
|
||||
result = query.Order("id desc").Offset(int(offset)).Limit(int(req.PageSize)).Find(&plans)
|
||||
if result.Error != nil {
|
||||
return &cronpb.PlanResponseList{
|
||||
Code: 500,
|
||||
Message: result.Error.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
data := make([]*cronpb.Plan, 0, len(plans))
|
||||
for _, plan := range plans {
|
||||
data = append(data, &cronpb.Plan{
|
||||
Id: uint32(plan.ID),
|
||||
Name: plan.Name,
|
||||
Enable: plan.Enabled,
|
||||
CreateTime: timestamppb.New(plan.CreatedAt),
|
||||
UpdateTime: timestamppb.New(plan.UpdatedAt),
|
||||
Plan: plan.Plan,
|
||||
})
|
||||
}
|
||||
|
||||
return &cronpb.PlanResponseList{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
TotalCount: uint32(total),
|
||||
PageNum: req.PageNum,
|
||||
PageSize: req.PageSize,
|
||||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ct *CrontabPlugin) Add(ctx context.Context, req *cronpb.Plan) (*cronpb.Response, error) {
|
||||
// 参数验证
|
||||
if strings.TrimSpace(req.Name) == "" {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "name is required",
|
||||
}, nil
|
||||
}
|
||||
|
||||
if strings.TrimSpace(req.Plan) == "" {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "plan is required",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 检查名称是否已存在
|
||||
var count int64
|
||||
if err := ct.DB.Model(&pkg.RecordPlan{}).Where("name = ?", req.Name).Count(&count).Error; err != nil {
|
||||
return &cronpb.Response{
|
||||
Code: 500,
|
||||
Message: err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if count > 0 {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "name already exists",
|
||||
}, nil
|
||||
}
|
||||
|
||||
plan := &pkg.RecordPlan{
|
||||
Name: req.Name,
|
||||
Plan: req.Plan,
|
||||
Enabled: req.Enable,
|
||||
}
|
||||
|
||||
if err := ct.DB.Create(plan).Error; err != nil {
|
||||
return &cronpb.Response{
|
||||
Code: 500,
|
||||
Message: err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &cronpb.Response{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ct *CrontabPlugin) Update(ctx context.Context, req *cronpb.Plan) (*cronpb.Response, error) {
|
||||
if req.Id == 0 {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "id is required",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 参数验证
|
||||
if strings.TrimSpace(req.Name) == "" {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "name is required",
|
||||
}, nil
|
||||
}
|
||||
|
||||
if strings.TrimSpace(req.Plan) == "" {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "plan is required",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 检查记录是否存在
|
||||
var existingPlan pkg.RecordPlan
|
||||
if err := ct.DB.First(&existingPlan, req.Id).Error; err != nil {
|
||||
return &cronpb.Response{
|
||||
Code: 404,
|
||||
Message: "record not found",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 检查新名称是否与其他记录冲突
|
||||
var count int64
|
||||
if err := ct.DB.Model(&pkg.RecordPlan{}).Where("name = ? AND id != ?", req.Name, req.Id).Count(&count).Error; err != nil {
|
||||
return &cronpb.Response{
|
||||
Code: 500,
|
||||
Message: err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if count > 0 {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "name already exists",
|
||||
}, nil
|
||||
}
|
||||
|
||||
updates := map[string]interface{}{
|
||||
"name": req.Name,
|
||||
"plan": req.Plan,
|
||||
"enabled": req.Enable,
|
||||
}
|
||||
|
||||
if err := ct.DB.Model(&existingPlan).Updates(updates).Error; err != nil {
|
||||
return &cronpb.Response{
|
||||
Code: 500,
|
||||
Message: err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &cronpb.Response{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ct *CrontabPlugin) Remove(ctx context.Context, req *cronpb.DeleteRequest) (*cronpb.Response, error) {
|
||||
if req.Id == 0 {
|
||||
return &cronpb.Response{
|
||||
Code: 400,
|
||||
Message: "id is required",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 检查记录是否存在
|
||||
var existingPlan pkg.RecordPlan
|
||||
if err := ct.DB.First(&existingPlan, req.Id).Error; err != nil {
|
||||
return &cronpb.Response{
|
||||
Code: 404,
|
||||
Message: "record not found",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 执行软删除
|
||||
if err := ct.DB.Delete(&existingPlan).Error; err != nil {
|
||||
return &cronpb.Response{
|
||||
Code: 500,
|
||||
Message: err.Error(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &cronpb.Response{
|
||||
Code: 0,
|
||||
Message: "success",
|
||||
}, nil
|
||||
}
|
||||
59
plugin/crontab/crontab.go
Normal file
59
plugin/crontab/crontab.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package plugin_crontab
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"m7s.live/v5/pkg/task"
|
||||
"m7s.live/v5/plugin/crontab/pkg"
|
||||
)
|
||||
|
||||
type Crontab struct {
|
||||
task.TickTask
|
||||
ctp *CrontabPlugin
|
||||
}
|
||||
|
||||
func (r *Crontab) GetTickInterval() time.Duration {
|
||||
return time.Minute
|
||||
}
|
||||
|
||||
func (r *Crontab) Tick(any) {
|
||||
r.Info("开始检查录制计划")
|
||||
|
||||
// 获取当前时间
|
||||
now := time.Now()
|
||||
// 计算当前是一周中的第几天(0-6, 0是周日)和当前小时(0-23)
|
||||
weekday := int(now.Weekday())
|
||||
if weekday == 0 {
|
||||
weekday = 7 // 将周日从0改为7,以便计算
|
||||
}
|
||||
hour := now.Hour()
|
||||
|
||||
// 计算当前时间对应的位置索引
|
||||
// (weekday-1)*24 + hour 得到当前时间在144位字符串中的位置
|
||||
// weekday-1 是因为我们要从周一开始计算
|
||||
index := (weekday-1)*24 + hour
|
||||
|
||||
// 查询所有启用的录制计划
|
||||
var plans []pkg.RecordPlan
|
||||
model := pkg.RecordPlan{
|
||||
Enabled: true,
|
||||
}
|
||||
if err := r.ctp.DB.Where(&model).Find(&plans).Error; err != nil {
|
||||
r.Error("查询录制计划失败:", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 遍历所有计划
|
||||
for _, plan := range plans {
|
||||
if len(plan.Plan) != 144 {
|
||||
r.Error("录制计划格式错误,plan长度应为144位:", plan.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查当前时间对应的位置是否为1
|
||||
if plan.Plan[index] == '1' {
|
||||
r.Info("检测到需要开启录像的计划:", plan.Name)
|
||||
// TODO: 在这里添加开启录像的逻辑
|
||||
}
|
||||
}
|
||||
}
|
||||
35
plugin/crontab/index.go
Normal file
35
plugin/crontab/index.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package plugin_crontab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"m7s.live/v5"
|
||||
"m7s.live/v5/plugin/crontab/pb"
|
||||
"m7s.live/v5/plugin/crontab/pkg"
|
||||
)
|
||||
|
||||
type CrontabPlugin struct {
|
||||
m7s.Plugin
|
||||
pb.UnimplementedApiServer
|
||||
}
|
||||
|
||||
var _ = m7s.InstallPlugin[CrontabPlugin](m7s.PluginMeta{
|
||||
ServiceDesc: &pb.Api_ServiceDesc,
|
||||
RegisterGRPCHandler: pb.RegisterApiHandler,
|
||||
})
|
||||
|
||||
func (ct *CrontabPlugin) OnInit() (err error) {
|
||||
if ct.DB == nil {
|
||||
ct.Error("DB is nil")
|
||||
} else {
|
||||
err = ct.DB.AutoMigrate(&pkg.RecordPlan{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("auto migrate tables error: %v", err)
|
||||
}
|
||||
ct.Info("init database success")
|
||||
}
|
||||
crontab := &Crontab{ctp: ct}
|
||||
ct.AddTask(crontab)
|
||||
crontab.Tick(nil)
|
||||
return
|
||||
}
|
||||
443
plugin/crontab/pb/crontab.pb.go
Normal file
443
plugin/crontab/pb/crontab.pb.go
Normal file
@@ -0,0 +1,443 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v5.29.3
|
||||
// source: crontab.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
_ "google.golang.org/genproto/googleapis/api/annotations"
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type PlanResponseList struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
|
||||
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
|
||||
TotalCount uint32 `protobuf:"varint,3,opt,name=totalCount,proto3" json:"totalCount,omitempty"`
|
||||
PageNum uint32 `protobuf:"varint,4,opt,name=pageNum,proto3" json:"pageNum,omitempty"`
|
||||
PageSize uint32 `protobuf:"varint,5,opt,name=pageSize,proto3" json:"pageSize,omitempty"`
|
||||
Data []*Plan `protobuf:"bytes,6,rep,name=data,proto3" json:"data,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) Reset() {
|
||||
*x = PlanResponseList{}
|
||||
mi := &file_crontab_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PlanResponseList) ProtoMessage() {}
|
||||
|
||||
func (x *PlanResponseList) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_crontab_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PlanResponseList.ProtoReflect.Descriptor instead.
|
||||
func (*PlanResponseList) Descriptor() ([]byte, []int) {
|
||||
return file_crontab_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) GetCode() int32 {
|
||||
if x != nil {
|
||||
return x.Code
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) GetMessage() string {
|
||||
if x != nil {
|
||||
return x.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) GetTotalCount() uint32 {
|
||||
if x != nil {
|
||||
return x.TotalCount
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) GetPageNum() uint32 {
|
||||
if x != nil {
|
||||
return x.PageNum
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) GetPageSize() uint32 {
|
||||
if x != nil {
|
||||
return x.PageSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *PlanResponseList) GetData() []*Plan {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Plan struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Enable bool `protobuf:"varint,3,opt,name=enable,proto3" json:"enable,omitempty"`
|
||||
CreateTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=createTime,proto3" json:"createTime,omitempty"`
|
||||
UpdateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updateTime,proto3" json:"updateTime,omitempty"`
|
||||
Plan string `protobuf:"bytes,6,opt,name=plan,proto3" json:"plan,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Plan) Reset() {
|
||||
*x = Plan{}
|
||||
mi := &file_crontab_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Plan) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Plan) ProtoMessage() {}
|
||||
|
||||
func (x *Plan) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_crontab_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Plan.ProtoReflect.Descriptor instead.
|
||||
func (*Plan) Descriptor() ([]byte, []int) {
|
||||
return file_crontab_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Plan) GetId() uint32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Plan) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Plan) GetEnable() bool {
|
||||
if x != nil {
|
||||
return x.Enable
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Plan) GetCreateTime() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.CreateTime
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Plan) GetUpdateTime() *timestamppb.Timestamp {
|
||||
if x != nil {
|
||||
return x.UpdateTime
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Plan) GetPlan() string {
|
||||
if x != nil {
|
||||
return x.Plan
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ReqPlanList struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
PageNum uint32 `protobuf:"varint,1,opt,name=pageNum,proto3" json:"pageNum,omitempty"`
|
||||
PageSize uint32 `protobuf:"varint,2,opt,name=pageSize,proto3" json:"pageSize,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ReqPlanList) Reset() {
|
||||
*x = ReqPlanList{}
|
||||
mi := &file_crontab_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ReqPlanList) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ReqPlanList) ProtoMessage() {}
|
||||
|
||||
func (x *ReqPlanList) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_crontab_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ReqPlanList.ProtoReflect.Descriptor instead.
|
||||
func (*ReqPlanList) Descriptor() ([]byte, []int) {
|
||||
return file_crontab_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *ReqPlanList) GetPageNum() uint32 {
|
||||
if x != nil {
|
||||
return x.PageNum
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ReqPlanList) GetPageSize() uint32 {
|
||||
if x != nil {
|
||||
return x.PageSize
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type DeleteRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *DeleteRequest) Reset() {
|
||||
*x = DeleteRequest{}
|
||||
mi := &file_crontab_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *DeleteRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*DeleteRequest) ProtoMessage() {}
|
||||
|
||||
func (x *DeleteRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_crontab_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use DeleteRequest.ProtoReflect.Descriptor instead.
|
||||
func (*DeleteRequest) Descriptor() ([]byte, []int) {
|
||||
return file_crontab_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *DeleteRequest) GetId() uint32 {
|
||||
if x != nil {
|
||||
return x.Id
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"`
|
||||
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Response) Reset() {
|
||||
*x = Response{}
|
||||
mi := &file_crontab_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Response) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Response) ProtoMessage() {}
|
||||
|
||||
func (x *Response) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_crontab_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Response.ProtoReflect.Descriptor instead.
|
||||
func (*Response) Descriptor() ([]byte, []int) {
|
||||
return file_crontab_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *Response) GetCode() int32 {
|
||||
if x != nil {
|
||||
return x.Code
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Response) GetMessage() string {
|
||||
if x != nil {
|
||||
return x.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_crontab_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_crontab_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\rcrontab.proto\x12\acrontab\x1a\x1cgoogle/api/annotations.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\xb9\x01\n" +
|
||||
"\x10PlanResponseList\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\x05R\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage\x12\x1e\n" +
|
||||
"\n" +
|
||||
"totalCount\x18\x03 \x01(\rR\n" +
|
||||
"totalCount\x12\x18\n" +
|
||||
"\apageNum\x18\x04 \x01(\rR\apageNum\x12\x1a\n" +
|
||||
"\bpageSize\x18\x05 \x01(\rR\bpageSize\x12!\n" +
|
||||
"\x04data\x18\x06 \x03(\v2\r.crontab.PlanR\x04data\"\xce\x01\n" +
|
||||
"\x04Plan\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\rR\x02id\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x01(\tR\x04name\x12\x16\n" +
|
||||
"\x06enable\x18\x03 \x01(\bR\x06enable\x12:\n" +
|
||||
"\n" +
|
||||
"createTime\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\n" +
|
||||
"createTime\x12:\n" +
|
||||
"\n" +
|
||||
"updateTime\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\n" +
|
||||
"updateTime\x12\x12\n" +
|
||||
"\x04plan\x18\x06 \x01(\tR\x04plan\"C\n" +
|
||||
"\vReqPlanList\x12\x18\n" +
|
||||
"\apageNum\x18\x01 \x01(\rR\apageNum\x12\x1a\n" +
|
||||
"\bpageSize\x18\x02 \x01(\rR\bpageSize\"\x1f\n" +
|
||||
"\rDeleteRequest\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\rR\x02id\"8\n" +
|
||||
"\bResponse\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\x05R\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage2\xbe\x02\n" +
|
||||
"\x03api\x12O\n" +
|
||||
"\x04List\x12\x14.crontab.ReqPlanList\x1a\x19.crontab.PlanResponseList\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/plan/api/list\x12A\n" +
|
||||
"\x03Add\x12\r.crontab.Plan\x1a\x11.crontab.Response\"\x18\x82\xd3\xe4\x93\x02\x12:\x01*\"\r/plan/api/add\x12L\n" +
|
||||
"\x06Update\x12\r.crontab.Plan\x1a\x11.crontab.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\"\x15/plan/api/update/{id}\x12U\n" +
|
||||
"\x06Remove\x12\x16.crontab.DeleteRequest\x1a\x11.crontab.Response\" \x82\xd3\xe4\x93\x02\x1a:\x01*\"\x15/plan/api/remove/{id}B\x1fZ\x1dm7s.live/v5/plugin/crontab/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_crontab_proto_rawDescOnce sync.Once
|
||||
file_crontab_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_crontab_proto_rawDescGZIP() []byte {
|
||||
file_crontab_proto_rawDescOnce.Do(func() {
|
||||
file_crontab_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_crontab_proto_rawDesc), len(file_crontab_proto_rawDesc)))
|
||||
})
|
||||
return file_crontab_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_crontab_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_crontab_proto_goTypes = []any{
|
||||
(*PlanResponseList)(nil), // 0: crontab.PlanResponseList
|
||||
(*Plan)(nil), // 1: crontab.Plan
|
||||
(*ReqPlanList)(nil), // 2: crontab.ReqPlanList
|
||||
(*DeleteRequest)(nil), // 3: crontab.DeleteRequest
|
||||
(*Response)(nil), // 4: crontab.Response
|
||||
(*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp
|
||||
}
|
||||
var file_crontab_proto_depIdxs = []int32{
|
||||
1, // 0: crontab.PlanResponseList.data:type_name -> crontab.Plan
|
||||
5, // 1: crontab.Plan.createTime:type_name -> google.protobuf.Timestamp
|
||||
5, // 2: crontab.Plan.updateTime:type_name -> google.protobuf.Timestamp
|
||||
2, // 3: crontab.api.List:input_type -> crontab.ReqPlanList
|
||||
1, // 4: crontab.api.Add:input_type -> crontab.Plan
|
||||
1, // 5: crontab.api.Update:input_type -> crontab.Plan
|
||||
3, // 6: crontab.api.Remove:input_type -> crontab.DeleteRequest
|
||||
0, // 7: crontab.api.List:output_type -> crontab.PlanResponseList
|
||||
4, // 8: crontab.api.Add:output_type -> crontab.Response
|
||||
4, // 9: crontab.api.Update:output_type -> crontab.Response
|
||||
4, // 10: crontab.api.Remove:output_type -> crontab.Response
|
||||
7, // [7:11] is the sub-list for method output_type
|
||||
3, // [3:7] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_crontab_proto_init() }
|
||||
func file_crontab_proto_init() {
|
||||
if File_crontab_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_crontab_proto_rawDesc), len(file_crontab_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_crontab_proto_goTypes,
|
||||
DependencyIndexes: file_crontab_proto_depIdxs,
|
||||
MessageInfos: file_crontab_proto_msgTypes,
|
||||
}.Build()
|
||||
File_crontab_proto = out.File
|
||||
file_crontab_proto_goTypes = nil
|
||||
file_crontab_proto_depIdxs = nil
|
||||
}
|
||||
388
plugin/crontab/pb/crontab.pb.gw.go
Normal file
388
plugin/crontab/pb/crontab.pb.gw.go
Normal file
@@ -0,0 +1,388 @@
|
||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: crontab.proto
|
||||
|
||||
/*
|
||||
Package pb is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package pb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var (
|
||||
_ codes.Code
|
||||
_ io.Reader
|
||||
_ status.Status
|
||||
_ = errors.New
|
||||
_ = runtime.String
|
||||
_ = utilities.NewDoubleArray
|
||||
_ = metadata.Join
|
||||
)
|
||||
|
||||
var filter_Api_List_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
|
||||
func request_Api_List_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq ReqPlanList
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
io.Copy(io.Discard, req.Body)
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_List_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := client.List(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_Api_List_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq ReqPlanList
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_List_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := server.List(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_Api_Add_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq Plan
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := client.Add(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_Api_Add_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq Plan
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
msg, err := server.Add(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_Api_Update_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq Plan
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
val, ok := pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
protoReq.Id, err = runtime.Uint32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
msg, err := client.Update(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_Api_Update_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq Plan
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
val, ok := pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
protoReq.Id, err = runtime.Uint32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
msg, err := server.Update(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func request_Api_Remove_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq DeleteRequest
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
val, ok := pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
protoReq.Id, err = runtime.Uint32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
msg, err := client.Remove(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
func local_request_Api_Remove_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq DeleteRequest
|
||||
metadata runtime.ServerMetadata
|
||||
err error
|
||||
)
|
||||
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
val, ok := pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
protoReq.Id, err = runtime.Uint32(val)
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
msg, err := server.Remove(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
}
|
||||
|
||||
// RegisterApiHandlerServer registers the http handlers for service Api to "mux".
|
||||
// UnaryRPC :call ApiServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterApiHandlerFromEndpoint instead.
|
||||
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
|
||||
func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ApiServer) error {
|
||||
mux.Handle(http.MethodGet, pattern_Api_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/crontab.Api/List", runtime.WithHTTPPathPattern("/plan/api/list"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Api_List_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_List_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_Api_Add_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/crontab.Api/Add", runtime.WithHTTPPathPattern("/plan/api/add"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Api_Add_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_Add_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_Api_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/crontab.Api/Update", runtime.WithHTTPPathPattern("/plan/api/update/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Api_Update_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_Update_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_Api_Remove_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/crontab.Api/Remove", runtime.WithHTTPPathPattern("/plan/api/remove/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Api_Remove_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_Remove_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterApiHandlerFromEndpoint is same as RegisterApiHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterApiHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.NewClient(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
return RegisterApiHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterApiHandler registers the http handlers for service Api to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterApiHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterApiHandlerClient(ctx, mux, NewApiClient(conn))
|
||||
}
|
||||
|
||||
// RegisterApiHandlerClient registers the http handlers for service Api
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ApiClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ApiClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "ApiClient" to call the correct interceptors. This client ignores the HTTP middlewares.
|
||||
func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ApiClient) error {
|
||||
mux.Handle(http.MethodGet, pattern_Api_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/crontab.Api/List", runtime.WithHTTPPathPattern("/plan/api/list"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Api_List_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_List_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_Api_Add_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/crontab.Api/Add", runtime.WithHTTPPathPattern("/plan/api/add"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Api_Add_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_Add_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_Api_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/crontab.Api/Update", runtime.WithHTTPPathPattern("/plan/api/update/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Api_Update_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_Update_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
mux.Handle(http.MethodPost, pattern_Api_Remove_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/crontab.Api/Remove", runtime.WithHTTPPathPattern("/plan/api/remove/{id}"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Api_Remove_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
forward_Api_Remove_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_Api_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"plan", "api", "list"}, ""))
|
||||
pattern_Api_Add_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"plan", "api", "add"}, ""))
|
||||
pattern_Api_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"plan", "api", "update", "id"}, ""))
|
||||
pattern_Api_Remove_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"plan", "api", "remove", "id"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_Api_List_0 = runtime.ForwardResponseMessage
|
||||
forward_Api_Add_0 = runtime.ForwardResponseMessage
|
||||
forward_Api_Update_0 = runtime.ForwardResponseMessage
|
||||
forward_Api_Remove_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
63
plugin/crontab/pb/crontab.proto
Normal file
63
plugin/crontab/pb/crontab.proto
Normal file
@@ -0,0 +1,63 @@
|
||||
syntax = "proto3";
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
package crontab;
|
||||
option go_package="m7s.live/v5/plugin/crontab/pb";
|
||||
|
||||
service api {
|
||||
rpc List (ReqPlanList) returns (PlanResponseList) {
|
||||
option (google.api.http) = {
|
||||
get: "/plan/api/list"
|
||||
};
|
||||
}
|
||||
rpc Add (Plan) returns (Response) {
|
||||
option (google.api.http) = {
|
||||
post: "/plan/api/add"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc Update (Plan) returns (Response) {
|
||||
option (google.api.http) = {
|
||||
post: "/plan/api/update/{id}"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc Remove (DeleteRequest) returns (Response) {
|
||||
option (google.api.http) = {
|
||||
post: "/plan/api/remove/{id}"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message PlanResponseList {
|
||||
int32 code = 1;
|
||||
string message = 2;
|
||||
uint32 totalCount = 3;
|
||||
uint32 pageNum = 4;
|
||||
uint32 pageSize = 5;
|
||||
repeated Plan data = 6;
|
||||
}
|
||||
|
||||
message Plan {
|
||||
uint32 id = 1;
|
||||
string name = 2;
|
||||
bool enable = 3;
|
||||
google.protobuf.Timestamp createTime = 4;
|
||||
google.protobuf.Timestamp updateTime = 5;
|
||||
string plan = 6;
|
||||
}
|
||||
|
||||
message ReqPlanList {
|
||||
uint32 pageNum = 1;
|
||||
uint32 pageSize = 2;
|
||||
}
|
||||
|
||||
message DeleteRequest {
|
||||
uint32 id = 1;
|
||||
}
|
||||
|
||||
message Response {
|
||||
int32 code = 1;
|
||||
string message = 2;
|
||||
}
|
||||
235
plugin/crontab/pb/crontab_grpc.pb.go
Normal file
235
plugin/crontab/pb/crontab_grpc.pb.go
Normal file
@@ -0,0 +1,235 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v5.29.3
|
||||
// source: crontab.proto
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
Api_List_FullMethodName = "/crontab.api/List"
|
||||
Api_Add_FullMethodName = "/crontab.api/Add"
|
||||
Api_Update_FullMethodName = "/crontab.api/Update"
|
||||
Api_Remove_FullMethodName = "/crontab.api/Remove"
|
||||
)
|
||||
|
||||
// ApiClient is the client API for Api service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type ApiClient interface {
|
||||
List(ctx context.Context, in *ReqPlanList, opts ...grpc.CallOption) (*PlanResponseList, error)
|
||||
Add(ctx context.Context, in *Plan, opts ...grpc.CallOption) (*Response, error)
|
||||
Update(ctx context.Context, in *Plan, opts ...grpc.CallOption) (*Response, error)
|
||||
Remove(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*Response, error)
|
||||
}
|
||||
|
||||
type apiClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewApiClient(cc grpc.ClientConnInterface) ApiClient {
|
||||
return &apiClient{cc}
|
||||
}
|
||||
|
||||
func (c *apiClient) List(ctx context.Context, in *ReqPlanList, opts ...grpc.CallOption) (*PlanResponseList, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(PlanResponseList)
|
||||
err := c.cc.Invoke(ctx, Api_List_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *apiClient) Add(ctx context.Context, in *Plan, opts ...grpc.CallOption) (*Response, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, Api_Add_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *apiClient) Update(ctx context.Context, in *Plan, opts ...grpc.CallOption) (*Response, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, Api_Update_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *apiClient) Remove(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*Response, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, Api_Remove_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ApiServer is the server API for Api service.
|
||||
// All implementations must embed UnimplementedApiServer
|
||||
// for forward compatibility.
|
||||
type ApiServer interface {
|
||||
List(context.Context, *ReqPlanList) (*PlanResponseList, error)
|
||||
Add(context.Context, *Plan) (*Response, error)
|
||||
Update(context.Context, *Plan) (*Response, error)
|
||||
Remove(context.Context, *DeleteRequest) (*Response, error)
|
||||
mustEmbedUnimplementedApiServer()
|
||||
}
|
||||
|
||||
// UnimplementedApiServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedApiServer struct{}
|
||||
|
||||
func (UnimplementedApiServer) List(context.Context, *ReqPlanList) (*PlanResponseList, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method List not implemented")
|
||||
}
|
||||
func (UnimplementedApiServer) Add(context.Context, *Plan) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Add not implemented")
|
||||
}
|
||||
func (UnimplementedApiServer) Update(context.Context, *Plan) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Update not implemented")
|
||||
}
|
||||
func (UnimplementedApiServer) Remove(context.Context, *DeleteRequest) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Remove not implemented")
|
||||
}
|
||||
func (UnimplementedApiServer) mustEmbedUnimplementedApiServer() {}
|
||||
func (UnimplementedApiServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeApiServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ApiServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeApiServer interface {
|
||||
mustEmbedUnimplementedApiServer()
|
||||
}
|
||||
|
||||
func RegisterApiServer(s grpc.ServiceRegistrar, srv ApiServer) {
|
||||
// If the following call pancis, it indicates UnimplementedApiServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&Api_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _Api_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ReqPlanList)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ApiServer).List(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Api_List_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApiServer).List(ctx, req.(*ReqPlanList))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Api_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Plan)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ApiServer).Add(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Api_Add_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApiServer).Add(ctx, req.(*Plan))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Api_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Plan)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ApiServer).Update(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Api_Update_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApiServer).Update(ctx, req.(*Plan))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Api_Remove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(DeleteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ApiServer).Remove(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Api_Remove_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApiServer).Remove(ctx, req.(*DeleteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Api_ServiceDesc is the grpc.ServiceDesc for Api service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var Api_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "crontab.api",
|
||||
HandlerType: (*ApiServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "List",
|
||||
Handler: _Api_List_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Add",
|
||||
Handler: _Api_Add_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Update",
|
||||
Handler: _Api_Update_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Remove",
|
||||
Handler: _Api_Remove_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "crontab.proto",
|
||||
}
|
||||
13
plugin/crontab/pkg/plan.go
Normal file
13
plugin/crontab/pkg/plan.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// RecordPlan 录制计划模型
|
||||
type RecordPlan struct {
|
||||
gorm.Model
|
||||
Name string `json:"name" gorm:"default:''"`
|
||||
Plan string `json:"plan" gorm:"type:text"`
|
||||
Enabled bool `json:"enabled" gorm:"default:true"`
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
"os/exec" // 新增导入
|
||||
"runtime"
|
||||
runtimePPROF "runtime/pprof"
|
||||
"sort"
|
||||
@@ -193,7 +194,7 @@ func (p *DebugPlugin) GetHeap(ctx context.Context, empty *emptypb.Empty) (*pb.He
|
||||
obj.Size += size
|
||||
totalSize += size
|
||||
|
||||
// 构建引<EFBFBD><EFBFBD><EFBFBD>关系
|
||||
// 构建引用关系
|
||||
for i := 1; i < len(sample.Location); i++ {
|
||||
loc := sample.Location[i]
|
||||
if len(loc.Line) == 0 || loc.Line[0].Function == nil {
|
||||
@@ -443,3 +444,44 @@ func (p *DebugPlugin) GetHeapGraph(ctx context.Context, empty *emptypb.Empty) (*
|
||||
Data: dot,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *DebugPlugin) StartTcpDump(ctx context.Context, req *pb.TcpDumpRequest) (*pb.TcpDumpResponse, error) {
|
||||
args := []string{}
|
||||
if req.Interface != "" {
|
||||
args = append(args, "-i", req.Interface)
|
||||
}
|
||||
if req.Duration > 0 {
|
||||
args = append(args, "-G", fmt.Sprintf("%d", req.Duration), "-W", "1")
|
||||
}
|
||||
if req.Filter != "" {
|
||||
args = append(args, req.Filter)
|
||||
}
|
||||
if req.ExtraArgs != "" {
|
||||
args = append(args, strings.Fields(req.ExtraArgs)...)
|
||||
}
|
||||
|
||||
cmd := exec.CommandContext(ctx, "tcpdump", args...)
|
||||
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
// 如果 tcpdump 因为超时而退出,这通常不是一个错误,而是预期的行为
|
||||
if exitErr, ok := err.(*exec.ExitError); ok && strings.Contains(string(exitErr.Stderr), "timeout") {
|
||||
return &pb.TcpDumpResponse{
|
||||
Code: 0,
|
||||
Message: "tcpdump completed with timeout as expected.",
|
||||
Data: string(output),
|
||||
}, nil
|
||||
}
|
||||
return &pb.TcpDumpResponse{
|
||||
Code: 1,
|
||||
Message: fmt.Sprintf("failed to run tcpdump: %v. Output: %s", err, string(output)),
|
||||
Data: string(output),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &pb.TcpDumpResponse{
|
||||
Code: 0,
|
||||
Message: "tcpdump completed successfully.",
|
||||
Data: string(output),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.0
|
||||
// protoc v5.29.1
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v5.29.3
|
||||
// source: debug.proto
|
||||
|
||||
package pb
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
_ "google.golang.org/protobuf/types/known/timestamppb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -1005,183 +1006,255 @@ func (x *RuntimeStats) GetBlockingTimeNs() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// TCP Dump请求参数
|
||||
type TcpDumpRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Interface string `protobuf:"bytes,1,opt,name=interface,proto3" json:"interface,omitempty"` // 网络接口 (例如: "eth0", "any"). 如果为空,可能由服务端决定默认值.
|
||||
Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` // BPF 过滤表达式 (例如: "port 80", "host 1.2.3.4 and tcp").
|
||||
Duration uint32 `protobuf:"varint,3,opt,name=duration,proto3" json:"duration,omitempty"` // 抓包持续时间(秒).
|
||||
ExtraArgs string `protobuf:"bytes,4,opt,name=extra_args,json=extraArgs,proto3" json:"extra_args,omitempty"` // 额外的 tcpdump 参数 (例如: "-n -X -c 100").
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *TcpDumpRequest) Reset() {
|
||||
*x = TcpDumpRequest{}
|
||||
mi := &file_debug_proto_msgTypes[14]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *TcpDumpRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TcpDumpRequest) ProtoMessage() {}
|
||||
|
||||
func (x *TcpDumpRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_debug_proto_msgTypes[14]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TcpDumpRequest.ProtoReflect.Descriptor instead.
|
||||
func (*TcpDumpRequest) Descriptor() ([]byte, []int) {
|
||||
return file_debug_proto_rawDescGZIP(), []int{14}
|
||||
}
|
||||
|
||||
func (x *TcpDumpRequest) GetInterface() string {
|
||||
if x != nil {
|
||||
return x.Interface
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TcpDumpRequest) GetFilter() string {
|
||||
if x != nil {
|
||||
return x.Filter
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TcpDumpRequest) GetDuration() uint32 {
|
||||
if x != nil {
|
||||
return x.Duration
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TcpDumpRequest) GetExtraArgs() string {
|
||||
if x != nil {
|
||||
return x.ExtraArgs
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// TCP Dump响应数据
|
||||
type TcpDumpResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` // 状态码 (0 表示成功)
|
||||
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` // 状态消息
|
||||
Data string `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` // tcpdump 的文本输出内容
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *TcpDumpResponse) Reset() {
|
||||
*x = TcpDumpResponse{}
|
||||
mi := &file_debug_proto_msgTypes[15]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *TcpDumpResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*TcpDumpResponse) ProtoMessage() {}
|
||||
|
||||
func (x *TcpDumpResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_debug_proto_msgTypes[15]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use TcpDumpResponse.ProtoReflect.Descriptor instead.
|
||||
func (*TcpDumpResponse) Descriptor() ([]byte, []int) {
|
||||
return file_debug_proto_rawDescGZIP(), []int{15}
|
||||
}
|
||||
|
||||
func (x *TcpDumpResponse) GetCode() uint32 {
|
||||
if x != nil {
|
||||
return x.Code
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *TcpDumpResponse) GetMessage() string {
|
||||
if x != nil {
|
||||
return x.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *TcpDumpResponse) GetData() string {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_debug_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_debug_proto_rawDesc = []byte{
|
||||
0x0a, 0x0b, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x64,
|
||||
0x65, 0x62, 0x75, 0x67, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69,
|
||||
0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
|
||||
0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x22, 0x42, 0x0a, 0x0a, 0x43, 0x70, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x01, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x70, 0x4f, 0x62, 0x6a,
|
||||
0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a,
|
||||
0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a,
|
||||
0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x69, 0x7a, 0x65, 0x50, 0x65, 0x72, 0x63, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x01, 0x52, 0x08, 0x73, 0x69, 0x7a, 0x65, 0x50, 0x65, 0x72, 0x63, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18,
|
||||
0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x66, 0x73, 0x22, 0xc7, 0x02, 0x0a, 0x09,
|
||||
0x48, 0x65, 0x61, 0x70, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x6c,
|
||||
0x6f, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x12,
|
||||
0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x73, 0x79, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73, 0x79,
|
||||
0x73, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x75, 0x6d, 0x47, 0x43, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d,
|
||||
0x52, 0x05, 0x6e, 0x75, 0x6d, 0x47, 0x43, 0x12, 0x1c, 0x0a, 0x09, 0x68, 0x65, 0x61, 0x70, 0x41,
|
||||
0x6c, 0x6c, 0x6f, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x68, 0x65, 0x61, 0x70,
|
||||
0x41, 0x6c, 0x6c, 0x6f, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x70, 0x53, 0x79, 0x73,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, 0x61, 0x70, 0x53, 0x79, 0x73, 0x12,
|
||||
0x1a, 0x0a, 0x08, 0x68, 0x65, 0x61, 0x70, 0x49, 0x64, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x04, 0x52, 0x08, 0x68, 0x65, 0x61, 0x70, 0x49, 0x64, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x68,
|
||||
0x65, 0x61, 0x70, 0x49, 0x6e, 0x75, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09,
|
||||
0x68, 0x65, 0x61, 0x70, 0x49, 0x6e, 0x75, 0x73, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x68, 0x65, 0x61,
|
||||
0x70, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x0c, 0x68, 0x65, 0x61, 0x70, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x68, 0x65, 0x61, 0x70, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x70, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12,
|
||||
0x24, 0x0a, 0x0d, 0x67, 0x63, 0x43, 0x50, 0x55, 0x46, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x67, 0x63, 0x43, 0x50, 0x55, 0x46, 0x72, 0x61,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x86, 0x01, 0x0a, 0x08, 0x48, 0x65, 0x61, 0x70, 0x44, 0x61,
|
||||
0x74, 0x61, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x10, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x53, 0x74,
|
||||
0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x12, 0x2b, 0x0a, 0x07, 0x6f, 0x62,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x64, 0x65,
|
||||
0x62, 0x75, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07,
|
||||
0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x05, 0x65, 0x64, 0x67, 0x65, 0x73,
|
||||
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x48,
|
||||
0x65, 0x61, 0x70, 0x45, 0x64, 0x67, 0x65, 0x52, 0x05, 0x65, 0x64, 0x67, 0x65, 0x73, 0x22, 0x4c,
|
||||
0x0a, 0x08, 0x48, 0x65, 0x61, 0x70, 0x45, 0x64, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72,
|
||||
0x6f, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e,
|
||||
0x0a, 0x02, 0x74, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x61, 0x0a, 0x0c,
|
||||
0x48, 0x65, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x04, 0x64, 0x61,
|
||||
0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67,
|
||||
0x2e, 0x48, 0x65, 0x61, 0x70, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22,
|
||||
0x55, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x70, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x54, 0x0a, 0x10, 0x43, 0x70, 0x75, 0x47, 0x72, 0x61,
|
||||
0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f,
|
||||
0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5f, 0x0a, 0x0b,
|
||||
0x43, 0x70, 0x75, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63,
|
||||
0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x04, 0x64, 0x61, 0x74,
|
||||
0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e,
|
||||
0x43, 0x70, 0x75, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xc5, 0x02,
|
||||
0x0a, 0x07, 0x43, 0x70, 0x75, 0x44, 0x61, 0x74, 0x61, 0x12, 0x29, 0x0a, 0x11, 0x74, 0x6f, 0x74,
|
||||
0x61, 0x6c, 0x5f, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x70, 0x75, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x4e, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67,
|
||||
0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x04, 0x52, 0x12, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x76, 0x61, 0x6c, 0x4e, 0x73, 0x12, 0x34, 0x0a, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x64, 0x65, 0x62, 0x75,
|
||||
0x67, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x52, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x0a,
|
||||
0x67, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x17, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x47, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69,
|
||||
0x6e, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x0a, 0x67, 0x6f, 0x72, 0x6f, 0x75,
|
||||
0x74, 0x69, 0x6e, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x0c, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f,
|
||||
0x63, 0x61, 0x6c, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x64, 0x65,
|
||||
0x62, 0x75, 0x67, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x0b,
|
||||
0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x61, 0x6c, 0x6c, 0x73, 0x12, 0x38, 0x0a, 0x0d, 0x72,
|
||||
0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x13, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xbf, 0x01, 0x0a, 0x0f, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x75, 0x6e,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e,
|
||||
0x0a, 0x0b, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x70, 0x75, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x29,
|
||||
0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x6c,
|
||||
0x6c, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63,
|
||||
0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x69,
|
||||
0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73,
|
||||
0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x77, 0x0a, 0x10, 0x47, 0x6f, 0x72, 0x6f, 0x75,
|
||||
0x74, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73,
|
||||
0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74,
|
||||
0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x70, 0x75, 0x54, 0x69, 0x6d, 0x65, 0x4e,
|
||||
0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18,
|
||||
0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x63, 0x6b,
|
||||
0x22, 0x56, 0x0a, 0x0a, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x63, 0x70, 0x75, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e,
|
||||
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x70, 0x75, 0x54, 0x69, 0x6d, 0x65,
|
||||
0x4e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xa4, 0x01, 0x0a, 0x0c, 0x52, 0x75, 0x6e,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x67, 0x63, 0x5f,
|
||||
0x63, 0x70, 0x75, 0x5f, 0x66, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x01, 0x52, 0x0d, 0x67, 0x63, 0x43, 0x70, 0x75, 0x46, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x63, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x63, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x10,
|
||||
0x67, 0x63, 0x5f, 0x70, 0x61, 0x75, 0x73, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x67, 0x63, 0x50, 0x61, 0x75, 0x73, 0x65, 0x54,
|
||||
0x69, 0x6d, 0x65, 0x4e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e,
|
||||
0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x32,
|
||||
0xd9, 0x02, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x12, 0x4f, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x48, 0x65,
|
||||
0x61, 0x70, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x13, 0x2e, 0x64, 0x65, 0x62,
|
||||
0x75, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11, 0x12, 0x0f, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f,
|
||||
0x61, 0x70, 0x69, 0x2f, 0x68, 0x65, 0x61, 0x70, 0x12, 0x5f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x48,
|
||||
0x65, 0x61, 0x70, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79,
|
||||
0x1a, 0x18, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x70, 0x47, 0x72, 0x61,
|
||||
0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x17, 0x12, 0x15, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68,
|
||||
0x65, 0x61, 0x70, 0x2f, 0x67, 0x72, 0x61, 0x70, 0x68, 0x12, 0x57, 0x0a, 0x0b, 0x47, 0x65, 0x74,
|
||||
0x43, 0x70, 0x75, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x11, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67,
|
||||
0x2e, 0x43, 0x70, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x64, 0x65,
|
||||
0x62, 0x75, 0x67, 0x2e, 0x43, 0x70, 0x75, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x64,
|
||||
0x65, 0x62, 0x75, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x70, 0x75, 0x2f, 0x67, 0x72, 0x61,
|
||||
0x70, 0x68, 0x12, 0x47, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x43, 0x70, 0x75, 0x12, 0x11, 0x2e, 0x64,
|
||||
0x65, 0x62, 0x75, 0x67, 0x2e, 0x43, 0x70, 0x75, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x12, 0x2e, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2e, 0x43, 0x70, 0x75, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x12, 0x0e, 0x2f, 0x64, 0x65,
|
||||
0x62, 0x75, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x70, 0x75, 0x42, 0x1d, 0x5a, 0x1b, 0x6d,
|
||||
0x37, 0x73, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69,
|
||||
0x6e, 0x2f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
const file_debug_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\vdebug.proto\x12\x05debug\x1a\x1cgoogle/api/annotations.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"B\n" +
|
||||
"\n" +
|
||||
"CpuRequest\x12\x18\n" +
|
||||
"\arefresh\x18\x01 \x01(\bR\arefresh\x12\x1a\n" +
|
||||
"\bduration\x18\x02 \x01(\rR\bduration\"\x94\x01\n" +
|
||||
"\n" +
|
||||
"HeapObject\x12\x12\n" +
|
||||
"\x04type\x18\x01 \x01(\tR\x04type\x12\x14\n" +
|
||||
"\x05count\x18\x02 \x01(\x03R\x05count\x12\x12\n" +
|
||||
"\x04size\x18\x03 \x01(\x03R\x04size\x12\x1a\n" +
|
||||
"\bsizePerc\x18\x04 \x01(\x01R\bsizePerc\x12\x18\n" +
|
||||
"\aaddress\x18\x05 \x01(\tR\aaddress\x12\x12\n" +
|
||||
"\x04refs\x18\x06 \x03(\tR\x04refs\"\xc7\x02\n" +
|
||||
"\tHeapStats\x12\x14\n" +
|
||||
"\x05alloc\x18\x01 \x01(\x04R\x05alloc\x12\x1e\n" +
|
||||
"\n" +
|
||||
"totalAlloc\x18\x02 \x01(\x04R\n" +
|
||||
"totalAlloc\x12\x10\n" +
|
||||
"\x03sys\x18\x03 \x01(\x04R\x03sys\x12\x14\n" +
|
||||
"\x05numGC\x18\x04 \x01(\rR\x05numGC\x12\x1c\n" +
|
||||
"\theapAlloc\x18\x05 \x01(\x04R\theapAlloc\x12\x18\n" +
|
||||
"\aheapSys\x18\x06 \x01(\x04R\aheapSys\x12\x1a\n" +
|
||||
"\bheapIdle\x18\a \x01(\x04R\bheapIdle\x12\x1c\n" +
|
||||
"\theapInuse\x18\b \x01(\x04R\theapInuse\x12\"\n" +
|
||||
"\fheapReleased\x18\t \x01(\x04R\fheapReleased\x12 \n" +
|
||||
"\vheapObjects\x18\n" +
|
||||
" \x01(\x04R\vheapObjects\x12$\n" +
|
||||
"\rgcCPUFraction\x18\v \x01(\x01R\rgcCPUFraction\"\x86\x01\n" +
|
||||
"\bHeapData\x12&\n" +
|
||||
"\x05stats\x18\x01 \x01(\v2\x10.debug.HeapStatsR\x05stats\x12+\n" +
|
||||
"\aobjects\x18\x02 \x03(\v2\x11.debug.HeapObjectR\aobjects\x12%\n" +
|
||||
"\x05edges\x18\x03 \x03(\v2\x0f.debug.HeapEdgeR\x05edges\"L\n" +
|
||||
"\bHeapEdge\x12\x12\n" +
|
||||
"\x04from\x18\x01 \x01(\tR\x04from\x12\x0e\n" +
|
||||
"\x02to\x18\x02 \x01(\tR\x02to\x12\x1c\n" +
|
||||
"\tfieldName\x18\x03 \x01(\tR\tfieldName\"a\n" +
|
||||
"\fHeapResponse\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\rR\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage\x12#\n" +
|
||||
"\x04data\x18\x03 \x01(\v2\x0f.debug.HeapDataR\x04data\"U\n" +
|
||||
"\x11HeapGraphResponse\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\rR\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage\x12\x12\n" +
|
||||
"\x04data\x18\x03 \x01(\tR\x04data\"T\n" +
|
||||
"\x10CpuGraphResponse\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\rR\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage\x12\x12\n" +
|
||||
"\x04data\x18\x03 \x01(\tR\x04data\"_\n" +
|
||||
"\vCpuResponse\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\rR\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage\x12\"\n" +
|
||||
"\x04data\x18\x03 \x01(\v2\x0e.debug.CpuDataR\x04data\"\xc5\x02\n" +
|
||||
"\aCpuData\x12)\n" +
|
||||
"\x11total_cpu_time_ns\x18\x01 \x01(\x04R\x0etotalCpuTimeNs\x120\n" +
|
||||
"\x14sampling_interval_ns\x18\x02 \x01(\x04R\x12samplingIntervalNs\x124\n" +
|
||||
"\tfunctions\x18\x03 \x03(\v2\x16.debug.FunctionProfileR\tfunctions\x127\n" +
|
||||
"\n" +
|
||||
"goroutines\x18\x04 \x03(\v2\x17.debug.GoroutineProfileR\n" +
|
||||
"goroutines\x124\n" +
|
||||
"\fsystem_calls\x18\x05 \x03(\v2\x11.debug.SystemCallR\vsystemCalls\x128\n" +
|
||||
"\rruntime_stats\x18\x06 \x01(\v2\x13.debug.RuntimeStatsR\fruntimeStats\"\xbf\x01\n" +
|
||||
"\x0fFunctionProfile\x12#\n" +
|
||||
"\rfunction_name\x18\x01 \x01(\tR\ffunctionName\x12\x1e\n" +
|
||||
"\vcpu_time_ns\x18\x02 \x01(\x04R\tcpuTimeNs\x12)\n" +
|
||||
"\x10invocation_count\x18\x03 \x01(\x04R\x0finvocationCount\x12\x1d\n" +
|
||||
"\n" +
|
||||
"call_stack\x18\x04 \x03(\tR\tcallStack\x12\x1d\n" +
|
||||
"\n" +
|
||||
"is_inlined\x18\x05 \x01(\bR\tisInlined\"w\n" +
|
||||
"\x10GoroutineProfile\x12\x0e\n" +
|
||||
"\x02id\x18\x01 \x01(\x04R\x02id\x12\x14\n" +
|
||||
"\x05state\x18\x02 \x01(\tR\x05state\x12\x1e\n" +
|
||||
"\vcpu_time_ns\x18\x03 \x01(\x04R\tcpuTimeNs\x12\x1d\n" +
|
||||
"\n" +
|
||||
"call_stack\x18\x04 \x03(\tR\tcallStack\"V\n" +
|
||||
"\n" +
|
||||
"SystemCall\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1e\n" +
|
||||
"\vcpu_time_ns\x18\x02 \x01(\x04R\tcpuTimeNs\x12\x14\n" +
|
||||
"\x05count\x18\x03 \x01(\x04R\x05count\"\xa4\x01\n" +
|
||||
"\fRuntimeStats\x12&\n" +
|
||||
"\x0fgc_cpu_fraction\x18\x01 \x01(\x01R\rgcCpuFraction\x12\x19\n" +
|
||||
"\bgc_count\x18\x02 \x01(\x04R\agcCount\x12'\n" +
|
||||
"\x10gc_pause_time_ns\x18\x03 \x01(\x04R\rgcPauseTimeNs\x12(\n" +
|
||||
"\x10blocking_time_ns\x18\x04 \x01(\x04R\x0eblockingTimeNs\"\x81\x01\n" +
|
||||
"\x0eTcpDumpRequest\x12\x1c\n" +
|
||||
"\tinterface\x18\x01 \x01(\tR\tinterface\x12\x16\n" +
|
||||
"\x06filter\x18\x02 \x01(\tR\x06filter\x12\x1a\n" +
|
||||
"\bduration\x18\x03 \x01(\rR\bduration\x12\x1d\n" +
|
||||
"\n" +
|
||||
"extra_args\x18\x04 \x01(\tR\textraArgs\"S\n" +
|
||||
"\x0fTcpDumpResponse\x12\x12\n" +
|
||||
"\x04code\x18\x01 \x01(\rR\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage\x12\x12\n" +
|
||||
"\x04data\x18\x03 \x01(\tR\x04data2\xb4\x03\n" +
|
||||
"\x03api\x12O\n" +
|
||||
"\aGetHeap\x12\x16.google.protobuf.Empty\x1a\x13.debug.HeapResponse\"\x17\x82\xd3\xe4\x93\x02\x11\x12\x0f/debug/api/heap\x12_\n" +
|
||||
"\fGetHeapGraph\x12\x16.google.protobuf.Empty\x1a\x18.debug.HeapGraphResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\x12\x15/debug/api/heap/graph\x12W\n" +
|
||||
"\vGetCpuGraph\x12\x11.debug.CpuRequest\x1a\x17.debug.CpuGraphResponse\"\x1c\x82\xd3\xe4\x93\x02\x16\x12\x14/debug/api/cpu/graph\x12G\n" +
|
||||
"\x06GetCpu\x12\x11.debug.CpuRequest\x1a\x12.debug.CpuResponse\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/debug/api/cpu\x12Y\n" +
|
||||
"\fStartTcpDump\x12\x15.debug.TcpDumpRequest\x1a\x16.debug.TcpDumpResponse\"\x1a\x82\xd3\xe4\x93\x02\x14\"\x12/debug/api/tcpdumpB\x1dZ\x1bm7s.live/v5/plugin/debug/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_debug_proto_rawDescOnce sync.Once
|
||||
file_debug_proto_rawDescData = file_debug_proto_rawDesc
|
||||
file_debug_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_debug_proto_rawDescGZIP() []byte {
|
||||
file_debug_proto_rawDescOnce.Do(func() {
|
||||
file_debug_proto_rawDescData = protoimpl.X.CompressGZIP(file_debug_proto_rawDescData)
|
||||
file_debug_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_debug_proto_rawDesc), len(file_debug_proto_rawDesc)))
|
||||
})
|
||||
return file_debug_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_debug_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||
var file_debug_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
|
||||
var file_debug_proto_goTypes = []any{
|
||||
(*CpuRequest)(nil), // 0: debug.CpuRequest
|
||||
(*HeapObject)(nil), // 1: debug.HeapObject
|
||||
@@ -1197,7 +1270,9 @@ var file_debug_proto_goTypes = []any{
|
||||
(*GoroutineProfile)(nil), // 11: debug.GoroutineProfile
|
||||
(*SystemCall)(nil), // 12: debug.SystemCall
|
||||
(*RuntimeStats)(nil), // 13: debug.RuntimeStats
|
||||
(*emptypb.Empty)(nil), // 14: google.protobuf.Empty
|
||||
(*TcpDumpRequest)(nil), // 14: debug.TcpDumpRequest
|
||||
(*TcpDumpResponse)(nil), // 15: debug.TcpDumpResponse
|
||||
(*emptypb.Empty)(nil), // 16: google.protobuf.Empty
|
||||
}
|
||||
var file_debug_proto_depIdxs = []int32{
|
||||
2, // 0: debug.HeapData.stats:type_name -> debug.HeapStats
|
||||
@@ -1209,16 +1284,18 @@ var file_debug_proto_depIdxs = []int32{
|
||||
11, // 6: debug.CpuData.goroutines:type_name -> debug.GoroutineProfile
|
||||
12, // 7: debug.CpuData.system_calls:type_name -> debug.SystemCall
|
||||
13, // 8: debug.CpuData.runtime_stats:type_name -> debug.RuntimeStats
|
||||
14, // 9: debug.api.GetHeap:input_type -> google.protobuf.Empty
|
||||
14, // 10: debug.api.GetHeapGraph:input_type -> google.protobuf.Empty
|
||||
16, // 9: debug.api.GetHeap:input_type -> google.protobuf.Empty
|
||||
16, // 10: debug.api.GetHeapGraph:input_type -> google.protobuf.Empty
|
||||
0, // 11: debug.api.GetCpuGraph:input_type -> debug.CpuRequest
|
||||
0, // 12: debug.api.GetCpu:input_type -> debug.CpuRequest
|
||||
5, // 13: debug.api.GetHeap:output_type -> debug.HeapResponse
|
||||
6, // 14: debug.api.GetHeapGraph:output_type -> debug.HeapGraphResponse
|
||||
7, // 15: debug.api.GetCpuGraph:output_type -> debug.CpuGraphResponse
|
||||
8, // 16: debug.api.GetCpu:output_type -> debug.CpuResponse
|
||||
13, // [13:17] is the sub-list for method output_type
|
||||
9, // [9:13] is the sub-list for method input_type
|
||||
14, // 13: debug.api.StartTcpDump:input_type -> debug.TcpDumpRequest
|
||||
5, // 14: debug.api.GetHeap:output_type -> debug.HeapResponse
|
||||
6, // 15: debug.api.GetHeapGraph:output_type -> debug.HeapGraphResponse
|
||||
7, // 16: debug.api.GetCpuGraph:output_type -> debug.CpuGraphResponse
|
||||
8, // 17: debug.api.GetCpu:output_type -> debug.CpuResponse
|
||||
15, // 18: debug.api.StartTcpDump:output_type -> debug.TcpDumpResponse
|
||||
14, // [14:19] is the sub-list for method output_type
|
||||
9, // [9:14] is the sub-list for method input_type
|
||||
9, // [9:9] is the sub-list for extension type_name
|
||||
9, // [9:9] is the sub-list for extension extendee
|
||||
0, // [0:9] is the sub-list for field type_name
|
||||
@@ -1233,9 +1310,9 @@ func file_debug_proto_init() {
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_debug_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_debug_proto_rawDesc), len(file_debug_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 14,
|
||||
NumMessages: 16,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
@@ -1244,7 +1321,6 @@ func file_debug_proto_init() {
|
||||
MessageInfos: file_debug_proto_msgTypes,
|
||||
}.Build()
|
||||
File_debug_proto = out.File
|
||||
file_debug_proto_rawDesc = nil
|
||||
file_debug_proto_goTypes = nil
|
||||
file_debug_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ package pb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
@@ -26,129 +25,172 @@ import (
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var (
|
||||
_ codes.Code
|
||||
_ io.Reader
|
||||
_ status.Status
|
||||
_ = errors.New
|
||||
_ = runtime.String
|
||||
_ = utilities.NewDoubleArray
|
||||
_ = metadata.Join
|
||||
)
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = metadata.Join
|
||||
|
||||
func request_Api_GetHeap_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq emptypb.Empty
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq emptypb.Empty
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.GetHeap(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Api_GetHeap_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq emptypb.Empty
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq emptypb.Empty
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.GetHeap(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Api_GetHeapGraph_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq emptypb.Empty
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq emptypb.Empty
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.GetHeapGraph(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Api_GetHeapGraph_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq emptypb.Empty
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq emptypb.Empty
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.GetHeapGraph(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var filter_Api_GetCpuGraph_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
var (
|
||||
filter_Api_GetCpuGraph_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Api_GetCpuGraph_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq CpuRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq CpuRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_GetCpuGraph_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetCpuGraph(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Api_GetCpuGraph_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq CpuRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq CpuRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_GetCpuGraph_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetCpuGraph(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var filter_Api_GetCpu_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
var (
|
||||
filter_Api_GetCpu_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Api_GetCpu_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq CpuRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq CpuRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_GetCpu_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetCpu(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Api_GetCpu_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var (
|
||||
protoReq CpuRequest
|
||||
metadata runtime.ServerMetadata
|
||||
)
|
||||
var protoReq CpuRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_GetCpu_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetCpu(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Api_StartTcpDump_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Api_StartTcpDump_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq TcpDumpRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_StartTcpDump_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.StartTcpDump(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Api_StartTcpDump_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq TcpDumpRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Api_StartTcpDump_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.StartTcpDump(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterApiHandlerServer registers the http handlers for service Api to "mux".
|
||||
// UnaryRPC :call ApiServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterApiHandlerFromEndpoint instead.
|
||||
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
|
||||
func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ApiServer) error {
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -160,15 +202,20 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetHeap_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -180,15 +227,20 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetHeapGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetCpuGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetCpuGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetCpuGraph", runtime.WithHTTPPathPattern("/debug/api/cpu/graph"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetCpuGraph", runtime.WithHTTPPathPattern("/debug/api/cpu/graph"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -200,15 +252,20 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetCpuGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetCpu_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetCpu_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetCpu", runtime.WithHTTPPathPattern("/debug/api/cpu"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/GetCpu", runtime.WithHTTPPathPattern("/debug/api/cpu"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -220,7 +277,34 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetCpu_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_Api_StartTcpDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/debug.Api/StartTcpDump", runtime.WithHTTPPathPattern("/debug/api/tcpdump"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Api_StartTcpDump_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_StartTcpDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
@@ -229,24 +313,25 @@ func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server
|
||||
// RegisterApiHandlerFromEndpoint is same as RegisterApiHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterApiHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.NewClient(endpoint, opts...)
|
||||
conn, err := grpc.DialContext(ctx, endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterApiHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
@@ -260,13 +345,16 @@ func RegisterApiHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.C
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ApiClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ApiClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "ApiClient" to call the correct interceptors. This client ignores the HTTP middlewares.
|
||||
// "ApiClient" to call the correct interceptors.
|
||||
func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ApiClient) error {
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetHeap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeap", runtime.WithHTTPPathPattern("/debug/api/heap"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -277,13 +365,18 @@ func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetHeap_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetHeapGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetHeapGraph", runtime.WithHTTPPathPattern("/debug/api/heap/graph"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -294,13 +387,18 @@ func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetHeapGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetCpuGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetCpuGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetCpuGraph", runtime.WithHTTPPathPattern("/debug/api/cpu/graph"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetCpuGraph", runtime.WithHTTPPathPattern("/debug/api/cpu/graph"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -311,13 +409,18 @@ func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetCpuGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
mux.Handle(http.MethodGet, pattern_Api_GetCpu_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
|
||||
mux.Handle("GET", pattern_Api_GetCpu_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetCpu", runtime.WithHTTPPathPattern("/debug/api/cpu"))
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/debug.Api/GetCpu", runtime.WithHTTPPathPattern("/debug/api/cpu"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
@@ -328,21 +431,56 @@ func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_GetCpu_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_Api_StartTcpDump_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/debug.Api/StartTcpDump", runtime.WithHTTPPathPattern("/debug/api/tcpdump"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Api_StartTcpDump_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Api_StartTcpDump_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_Api_GetHeap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "heap"}, ""))
|
||||
pattern_Api_GetHeap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "heap"}, ""))
|
||||
|
||||
pattern_Api_GetHeapGraph_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"debug", "api", "heap", "graph"}, ""))
|
||||
pattern_Api_GetCpuGraph_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"debug", "api", "cpu", "graph"}, ""))
|
||||
pattern_Api_GetCpu_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "cpu"}, ""))
|
||||
|
||||
pattern_Api_GetCpuGraph_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"debug", "api", "cpu", "graph"}, ""))
|
||||
|
||||
pattern_Api_GetCpu_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "cpu"}, ""))
|
||||
|
||||
pattern_Api_StartTcpDump_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"debug", "api", "tcpdump"}, ""))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_Api_GetHeap_0 = runtime.ForwardResponseMessage
|
||||
forward_Api_GetHeap_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Api_GetHeapGraph_0 = runtime.ForwardResponseMessage
|
||||
forward_Api_GetCpuGraph_0 = runtime.ForwardResponseMessage
|
||||
forward_Api_GetCpu_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Api_GetCpuGraph_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Api_GetCpu_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Api_StartTcpDump_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
@@ -26,6 +26,12 @@ service api {
|
||||
get: "/debug/api/cpu"
|
||||
};
|
||||
}
|
||||
|
||||
rpc StartTcpDump (TcpDumpRequest) returns (TcpDumpResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/debug/api/tcpdump"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// CPU分析请求参数
|
||||
@@ -132,4 +138,19 @@ message RuntimeStats {
|
||||
uint64 gc_count = 2; // 垃圾回收次数
|
||||
uint64 gc_pause_time_ns = 3; // 垃圾回收暂停时间(纳秒)
|
||||
uint64 blocking_time_ns = 4; // 阻塞时间(纳秒)
|
||||
}
|
||||
|
||||
// TCP Dump请求参数
|
||||
message TcpDumpRequest {
|
||||
string interface = 1; // 网络接口 (例如: "eth0", "any"). 如果为空,可能由服务端决定默认值.
|
||||
string filter = 2; // BPF 过滤表达式 (例如: "port 80", "host 1.2.3.4 and tcp").
|
||||
uint32 duration = 3; // 抓包持续时间(秒).
|
||||
string extra_args = 4; // 额外的 tcpdump 参数 (例如: "-n -X -c 100").
|
||||
}
|
||||
|
||||
// TCP Dump响应数据
|
||||
message TcpDumpResponse {
|
||||
uint32 code = 1; // 状态码 (0 表示成功)
|
||||
string message = 2; // 状态消息
|
||||
string data = 3; // tcpdump 的文本输出内容
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v5.29.1
|
||||
// - protoc v5.29.3
|
||||
// source: debug.proto
|
||||
|
||||
package pb
|
||||
@@ -24,6 +24,7 @@ const (
|
||||
Api_GetHeapGraph_FullMethodName = "/debug.api/GetHeapGraph"
|
||||
Api_GetCpuGraph_FullMethodName = "/debug.api/GetCpuGraph"
|
||||
Api_GetCpu_FullMethodName = "/debug.api/GetCpu"
|
||||
Api_StartTcpDump_FullMethodName = "/debug.api/StartTcpDump"
|
||||
)
|
||||
|
||||
// ApiClient is the client API for Api service.
|
||||
@@ -34,6 +35,7 @@ type ApiClient interface {
|
||||
GetHeapGraph(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HeapGraphResponse, error)
|
||||
GetCpuGraph(ctx context.Context, in *CpuRequest, opts ...grpc.CallOption) (*CpuGraphResponse, error)
|
||||
GetCpu(ctx context.Context, in *CpuRequest, opts ...grpc.CallOption) (*CpuResponse, error)
|
||||
StartTcpDump(ctx context.Context, in *TcpDumpRequest, opts ...grpc.CallOption) (*TcpDumpResponse, error)
|
||||
}
|
||||
|
||||
type apiClient struct {
|
||||
@@ -84,6 +86,16 @@ func (c *apiClient) GetCpu(ctx context.Context, in *CpuRequest, opts ...grpc.Cal
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *apiClient) StartTcpDump(ctx context.Context, in *TcpDumpRequest, opts ...grpc.CallOption) (*TcpDumpResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(TcpDumpResponse)
|
||||
err := c.cc.Invoke(ctx, Api_StartTcpDump_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// ApiServer is the server API for Api service.
|
||||
// All implementations must embed UnimplementedApiServer
|
||||
// for forward compatibility.
|
||||
@@ -92,6 +104,7 @@ type ApiServer interface {
|
||||
GetHeapGraph(context.Context, *emptypb.Empty) (*HeapGraphResponse, error)
|
||||
GetCpuGraph(context.Context, *CpuRequest) (*CpuGraphResponse, error)
|
||||
GetCpu(context.Context, *CpuRequest) (*CpuResponse, error)
|
||||
StartTcpDump(context.Context, *TcpDumpRequest) (*TcpDumpResponse, error)
|
||||
mustEmbedUnimplementedApiServer()
|
||||
}
|
||||
|
||||
@@ -114,6 +127,9 @@ func (UnimplementedApiServer) GetCpuGraph(context.Context, *CpuRequest) (*CpuGra
|
||||
func (UnimplementedApiServer) GetCpu(context.Context, *CpuRequest) (*CpuResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetCpu not implemented")
|
||||
}
|
||||
func (UnimplementedApiServer) StartTcpDump(context.Context, *TcpDumpRequest) (*TcpDumpResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method StartTcpDump not implemented")
|
||||
}
|
||||
func (UnimplementedApiServer) mustEmbedUnimplementedApiServer() {}
|
||||
func (UnimplementedApiServer) testEmbeddedByValue() {}
|
||||
|
||||
@@ -207,6 +223,24 @@ func _Api_GetCpu_Handler(srv interface{}, ctx context.Context, dec func(interfac
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Api_StartTcpDump_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(TcpDumpRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ApiServer).StartTcpDump(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Api_StartTcpDump_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApiServer).StartTcpDump(ctx, req.(*TcpDumpRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Api_ServiceDesc is the grpc.ServiceDesc for Api service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
@@ -230,6 +264,10 @@ var Api_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "GetCpu",
|
||||
Handler: _Api_GetCpu_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "StartTcpDump",
|
||||
Handler: _Api_StartTcpDump_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "debug.proto",
|
||||
|
||||
@@ -86,7 +86,8 @@ func (gb *GB28181Plugin) List(ctx context.Context, req *pb.GetDevicesRequest) (*
|
||||
for _, c := range channels {
|
||||
pbChannels = append(pbChannels, &pb.Channel{
|
||||
DeviceId: c.ChannelID,
|
||||
ParentId: c.ParentID,
|
||||
ParentId: c.DeviceID,
|
||||
ChannelId: c.ChannelID,
|
||||
Name: c.Name,
|
||||
Manufacturer: c.Manufacturer,
|
||||
Model: c.Model,
|
||||
|
||||
@@ -80,7 +80,7 @@ type Device struct {
|
||||
fromHDR sip.FromHeader
|
||||
toHDR sip.ToHeader
|
||||
plugin *GB28181Plugin `gorm:"-:all"`
|
||||
localPort int
|
||||
LocalPort int
|
||||
CatalogSubscribeTask *CatalogSubscribeTask `gorm:"-:all"`
|
||||
PositionSubscribeTask *PositionSubscribeTask `gorm:"-:all"`
|
||||
AlarmSubscribeTask *AlarmSubscribeTask `gorm:"-:all"`
|
||||
@@ -101,7 +101,7 @@ func (d *Device) Dispose() {
|
||||
})
|
||||
} else {
|
||||
// 如果没有通道,则直接更新通道状态为 OFF
|
||||
d.plugin.DB.Model(&gb28181.DeviceChannel{}).Where("device_db_id = ?", d.ID).Update("status", "OFF")
|
||||
d.plugin.DB.Model(&gb28181.DeviceChannel{}).Where("device_id = ?", d.ID).Update("status", "OFF")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,6 +140,7 @@ func (r *CatalogRequest) IsComplete(channelsLength int) bool {
|
||||
}
|
||||
|
||||
func (d *Device) onMessage(req *sip.Request, tx sip.ServerTransaction, msg *gb28181.Message) (err error) {
|
||||
d.plugin.Debug("into onMessage,deviceid is ", d.DeviceId)
|
||||
source := req.Source()
|
||||
hostname, portStr, _ := net.SplitHostPort(source)
|
||||
port, _ := strconv.Atoi(portStr)
|
||||
@@ -160,6 +161,7 @@ func (d *Device) onMessage(req *sip.Request, tx sip.ServerTransaction, msg *gb28
|
||||
case "Keepalive":
|
||||
d.KeepaliveInterval = int(time.Since(d.KeepaliveTime).Seconds())
|
||||
d.KeepaliveTime = time.Now()
|
||||
d.Debug("into keeplive,deviceid is ", d.DeviceId, "d.KeepaliveTime is", d.KeepaliveTime)
|
||||
if d.plugin.DB != nil {
|
||||
if err := d.plugin.DB.Model(d).Updates(map[string]interface{}{
|
||||
"keepalive_interval": d.KeepaliveInterval,
|
||||
@@ -403,6 +405,7 @@ func (d *Device) send(req *sip.Request) (*sip.Response, error) {
|
||||
}
|
||||
|
||||
func (d *Device) Go() (err error) {
|
||||
d.Debug("into device.Go,deviceid is ", d.DeviceId)
|
||||
var response *sip.Response
|
||||
|
||||
// 初始化catalogReqs
|
||||
@@ -447,6 +450,7 @@ func (d *Device) Go() (err error) {
|
||||
select {
|
||||
case <-d.Done():
|
||||
case <-keepLiveTick.C:
|
||||
d.Debug("keepLiveTick,deviceid is", d.DeviceId, "d.KeepaliveTime is ", d.KeepaliveTime)
|
||||
if timeDiff := time.Since(d.KeepaliveTime); timeDiff > time.Duration(3*keepaliveSeconds)*time.Second {
|
||||
d.Online = false
|
||||
d.Status = DeviceOfflineStatus
|
||||
@@ -455,7 +459,7 @@ func (d *Device) Go() (err error) {
|
||||
channel.Status = "OFF"
|
||||
return true
|
||||
})
|
||||
d.Stop(fmt.Errorf("device keepalive timeout after %v", timeDiff))
|
||||
d.Stop(fmt.Errorf("device keepalive timeout after %v,deviceid is %s", timeDiff, d.DeviceId))
|
||||
return
|
||||
}
|
||||
case <-catalogTick.C:
|
||||
@@ -519,7 +523,7 @@ func (d *Device) CreateRequest(Method sip.RequestMethod, Recipient any) *sip.Req
|
||||
// ProtocolVersion: "2.0",
|
||||
// Transport: "UDP",
|
||||
// Host: d.SipIp,
|
||||
// Port: d.localPort,
|
||||
// Port: d.LocalPort,
|
||||
// Params: sip.HeaderParams(sip.NewParams()),
|
||||
//}
|
||||
//viaHeader.Params.Add("branch", sip.GenerateBranchN(10)).Add("rport", "")
|
||||
|
||||
@@ -30,6 +30,17 @@ type Dialog struct {
|
||||
StreamMode string // 数据流传输模式(UDP:udp传输/TCP-ACTIVE:tcp主动模式/TCP-PASSIVE:tcp被动模式)
|
||||
targetIP string // 目标设备的IP地址
|
||||
targetPort int // 目标设备的端口
|
||||
/**
|
||||
子码流的配置,默认格式为:
|
||||
stream=stream:0;stream=stream:1
|
||||
GB28181-2022:
|
||||
stream=streanumber:0;stream=streamnumber:1
|
||||
大华为:
|
||||
stream=streamprofile:0;stream=streamprofile:1
|
||||
水星,tp-link:
|
||||
stream=streamMode:main;stream=streamMode:sub
|
||||
*/
|
||||
stream string
|
||||
}
|
||||
|
||||
func (d *Dialog) GetCallID() string {
|
||||
@@ -135,6 +146,9 @@ func (d *Dialog) Start() (err error) {
|
||||
|
||||
sdpInfo = append(sdpInfo, mediaLine)
|
||||
sdpInfo = append(sdpInfo, "a=recvonly")
|
||||
if d.stream != "" {
|
||||
sdpInfo = append(sdpInfo, "a="+d.stream)
|
||||
}
|
||||
|
||||
//根据传输模式添加 setup 和 connection 属性
|
||||
switch strings.ToUpper(device.StreamMode) {
|
||||
@@ -185,7 +199,7 @@ func (d *Dialog) Start() (err error) {
|
||||
ProtocolVersion: "2.0",
|
||||
Transport: "UDP",
|
||||
Host: device.MediaIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
Params: sip.NewParams(),
|
||||
}
|
||||
viaHeader.Params.Add("branch", sip.GenerateBranchN(10)).Add("rport", "")
|
||||
@@ -199,8 +213,8 @@ func (d *Dialog) Start() (err error) {
|
||||
contactHDR := sip.ContactHeader{
|
||||
Address: sip.Uri{
|
||||
User: d.gb.Serial,
|
||||
Host: device.SipIp,
|
||||
Port: device.localPort,
|
||||
Host: device.MediaIp,
|
||||
Port: device.LocalPort,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -208,12 +222,12 @@ func (d *Dialog) Start() (err error) {
|
||||
Address: sip.Uri{
|
||||
User: d.gb.Serial,
|
||||
Host: device.MediaIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
},
|
||||
Params: sip.NewParams(),
|
||||
}
|
||||
fromHDR.Params.Add("tag", sip.GenerateTagN(32))
|
||||
dialogClientCache := sipgo.NewDialogClientCache(device.client, device.contactHDR)
|
||||
dialogClientCache := sipgo.NewDialogClientCache(device.client, contactHDR)
|
||||
// 创建会话
|
||||
d.gb.Info("start to invite,recipient:", recipient, " viaHeader:", viaHeader, " fromHDR:", fromHDR, " toHeader:", toHeader, " device.contactHDR:", device.contactHDR, "contactHDR:", contactHDR)
|
||||
// 判断当前系统类型
|
||||
@@ -223,6 +237,9 @@ func (d *Dialog) Start() (err error) {
|
||||
d.session, err = dialogClientCache.Invite(d.gb, recipient, []byte(strings.Join(sdpInfo, "\r\n")+"\r\n"), &callID, &csqHeader, &fromHDR, &toHeader, &maxforward, userAgentHeader, subjectHeader, &contentTypeHeader)
|
||||
//}
|
||||
// 最后添加Content-Length头部
|
||||
if err != nil {
|
||||
d.gb.Error("invite error", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -230,6 +247,7 @@ func (d *Dialog) Run() (err error) {
|
||||
d.Channel.Info("before WaitAnswer")
|
||||
err = d.session.WaitAnswer(d.gb, sipgo.AnswerOptions{})
|
||||
d.Channel.Info("after WaitAnswer")
|
||||
d.gb.Error(" WaitAnswer error", err)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ func (d *ForwardDialog) Start() (err error) {
|
||||
ProtocolVersion: "2.0",
|
||||
Transport: "UDP",
|
||||
Host: device.SipIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
Params: sip.HeaderParams(sip.NewParams()),
|
||||
}
|
||||
viaHeader.Params.Add("branch", sip.GenerateBranchN(16)).Add("rport", "")
|
||||
@@ -199,7 +199,7 @@ func (d *ForwardDialog) Start() (err error) {
|
||||
Address: sip.Uri{
|
||||
User: d.gb.Serial,
|
||||
Host: device.MediaIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
},
|
||||
Params: sip.NewParams(),
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ func (gb *GB28181Plugin) checkDeviceExpire() (err error) {
|
||||
Address: sip.Uri{
|
||||
User: gb.Serial,
|
||||
Host: device.SipIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ func (gb *GB28181Plugin) checkDeviceExpire() (err error) {
|
||||
Address: sip.Uri{
|
||||
User: gb.Serial,
|
||||
Host: device.SipIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
},
|
||||
Params: sip.NewParams(),
|
||||
}
|
||||
@@ -262,7 +262,7 @@ func (gb *GB28181Plugin) checkDeviceExpire() (err error) {
|
||||
|
||||
// 创建SIP客户端
|
||||
device.client, _ = sipgo.NewClient(gb.ua, sipgo.WithClientLogger(zerolog.New(os.Stdout)), sipgo.WithClientHostname(device.SipIp))
|
||||
device.Info("checkDeviceExpire", "d.SipIp", device.SipIp, "d.localPort", device.localPort, "d.contactHDR", device.contactHDR)
|
||||
device.Info("checkDeviceExpire", "d.SipIp", device.SipIp, "d.LocalPort", device.LocalPort, "d.contactHDR", device.contactHDR)
|
||||
|
||||
// 设置设备ID的hash值作为任务ID
|
||||
var hash uint32
|
||||
@@ -545,13 +545,17 @@ func (gb *GB28181Plugin) OnRegister(req *sip.Request, tx sip.ServerTransaction)
|
||||
d.Stop(errors.New("unregister"))
|
||||
}
|
||||
} else {
|
||||
if d, ok := gb.devices.Get(deviceid); ok && d.Online {
|
||||
if d, ok := gb.devices.Get(deviceid); ok {
|
||||
gb.Info("into recoverdevice", "deviceId", d.DeviceId)
|
||||
d.Status = DeviceOnlineStatus
|
||||
gb.RecoverDevice(d, req)
|
||||
gb.StoreDevice(deviceid, req, d)
|
||||
} else {
|
||||
d := &Device{
|
||||
DeviceId: deviceid,
|
||||
}
|
||||
gb.devices.Set(d)
|
||||
gb.Info("into StoreDevice", "deviceId", from)
|
||||
gb.StoreDevice(deviceid, req)
|
||||
gb.StoreDevice(deviceid, req, d)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -560,7 +564,7 @@ func (gb *GB28181Plugin) OnMessage(req *sip.Request, tx sip.ServerTransaction) {
|
||||
// 解析消息内容
|
||||
temp := &gb28181.Message{}
|
||||
err := gb28181.DecodeXML(temp, req.Body())
|
||||
gb.Debug("onmessage debug", "message", temp)
|
||||
gb.Debug("OnMessage debug", "message", temp)
|
||||
if err != nil {
|
||||
gb.Error("OnMessage", "error", err.Error())
|
||||
response := sip.NewResponseFromRequest(req, sip.StatusBadRequest, "Bad Request", nil)
|
||||
@@ -591,8 +595,9 @@ func (gb *GB28181Plugin) OnMessage(req *sip.Request, tx sip.ServerTransaction) {
|
||||
}
|
||||
}
|
||||
|
||||
gb.Debug("00000000000001,deviceid is ", id)
|
||||
// 如果设备和平台都存在,通过源地址判断真实来源
|
||||
if d != nil && p != nil {
|
||||
if d != nil && d.Online && p != nil {
|
||||
source := req.Source()
|
||||
if d.HostAddress == source {
|
||||
// 如果源地址匹配设备地址,则确认是设备消息
|
||||
@@ -602,9 +607,10 @@ func (gb *GB28181Plugin) OnMessage(req *sip.Request, tx sip.ServerTransaction) {
|
||||
d = nil
|
||||
}
|
||||
}
|
||||
gb.Debug("00000000000002,deviceid is ", id)
|
||||
|
||||
// 如果既不是设备也不是平台,返回404
|
||||
if d == nil && p == nil {
|
||||
if (d == nil && p == nil) || (d != nil && !d.Online) {
|
||||
var response *sip.Response
|
||||
gb.Info("OnMessage", "error", "device/platform not found", "id", id)
|
||||
response = sip.NewResponseFromRequest(req, sip.StatusNotFound, "Not Found", nil)
|
||||
@@ -614,12 +620,13 @@ func (gb *GB28181Plugin) OnMessage(req *sip.Request, tx sip.ServerTransaction) {
|
||||
gb.Debug("after on message respond")
|
||||
return
|
||||
}
|
||||
gb.Debug("00000000000003,deviceid is ", id)
|
||||
|
||||
// 根据来源调用不同的处理方法
|
||||
if d != nil {
|
||||
if d != nil && d.Online {
|
||||
d.UpdateTime = time.Now()
|
||||
if err = d.onMessage(req, tx, temp); err != nil {
|
||||
gb.Error("onMessage", "error", err.Error(), "type", "device")
|
||||
gb.Error("onMessage", "error", err.Error(), "type", "device,deviceid is", d.DeviceId)
|
||||
}
|
||||
} else {
|
||||
var platform *Platform
|
||||
@@ -787,21 +794,22 @@ func (gb *GB28181Plugin) RecoverDevice(d *Device, req *sip.Request) {
|
||||
d.client, _ = sipgo.NewClient(gb.ua, sipgo.WithClientLogger(zerolog.New(os.Stdout)), sipgo.WithClientHostname(d.SipIp))
|
||||
d.channels.L = new(sync.RWMutex)
|
||||
d.catalogReqs.L = new(sync.RWMutex)
|
||||
d.Info("StoreDevice", "source", source, "desc", desc, "device.SipIp", myLanIP, "device.WanIP", myWanIP, "recipient", req.Recipient, "myPort", myPort)
|
||||
d.plugin = gb
|
||||
d.plugin.Info("RecoverDevice", "source", source, "desc", desc, "device.SipIp", myLanIP, "device.WanIP", myWanIP, "recipient", req.Recipient, "myPort", myPort)
|
||||
|
||||
if gb.DB != nil {
|
||||
var existing Device
|
||||
if err := gb.DB.First(&existing, Device{DeviceId: d.DeviceId}).Error; err == nil {
|
||||
d.ID = existing.ID // 保持原有的自增ID
|
||||
gb.Info("RecoverDevice", "type", "更新设备", "deviceId", d.DeviceId)
|
||||
} else {
|
||||
gb.Info("RecoverDevice", "type", "新增设备", "deviceId", d.DeviceId)
|
||||
}
|
||||
//var existing Device
|
||||
//if err := gb.DB.First(&existing, Device{DeviceId: d.DeviceId}).Error; err == nil {
|
||||
// d.ID = existing.ID // 保持原有的自增ID
|
||||
// gb.Info("RecoverDevice", "type", "更新设备", "deviceId", d.DeviceId)
|
||||
//} else {
|
||||
// gb.Info("RecoverDevice", "type", "新增设备", "deviceId", d.DeviceId)
|
||||
//}
|
||||
gb.DB.Save(d)
|
||||
}
|
||||
}
|
||||
|
||||
func (gb *GB28181Plugin) StoreDevice(deviceid string, req *sip.Request) (d *Device) {
|
||||
func (gb *GB28181Plugin) StoreDevice(deviceid string, req *sip.Request, d *Device) {
|
||||
source := req.Source()
|
||||
sourceIP, sourcePortStr, _ := net.SplitHostPort(source)
|
||||
sourcePort, _ := strconv.Atoi(sourcePortStr)
|
||||
@@ -866,48 +874,45 @@ func (gb *GB28181Plugin) StoreDevice(deviceid string, req *sip.Request) (d *Devi
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
d = &Device{
|
||||
DeviceId: deviceid,
|
||||
CreateTime: now,
|
||||
UpdateTime: now,
|
||||
RegisterTime: now,
|
||||
KeepaliveTime: now,
|
||||
Status: DeviceOnlineStatus,
|
||||
Online: true,
|
||||
StreamMode: "TCP-PASSIVE", // 默认UDP传输
|
||||
Charset: "GB2312", // 默认GB2312字符集
|
||||
GeoCoordSys: "WGS84", // 默认WGS84坐标系
|
||||
Transport: req.Transport(), // 传输协议
|
||||
IP: sourceIP,
|
||||
Port: sourcePort,
|
||||
HostAddress: sourceIP + ":" + sourcePortStr,
|
||||
SipIp: myLanIP,
|
||||
MediaIp: myWanIP,
|
||||
Expires: int(expSec),
|
||||
eventChan: make(chan any, 10),
|
||||
Recipient: sip.Uri{
|
||||
Host: sourceIP,
|
||||
Port: sourcePort,
|
||||
User: deviceid,
|
||||
},
|
||||
contactHDR: sip.ContactHeader{
|
||||
Address: sip.Uri{
|
||||
User: gb.Serial,
|
||||
Host: myWanIP,
|
||||
Port: myPort,
|
||||
},
|
||||
},
|
||||
fromHDR: sip.FromHeader{
|
||||
Address: sip.Uri{
|
||||
User: gb.Serial,
|
||||
Host: myWanIP,
|
||||
Port: myPort,
|
||||
},
|
||||
Params: sip.NewParams(),
|
||||
},
|
||||
plugin: gb,
|
||||
localPort: myPort,
|
||||
d.CreateTime = now
|
||||
d.UpdateTime = now
|
||||
d.RegisterTime = now
|
||||
d.KeepaliveTime = now
|
||||
d.Status = DeviceOnlineStatus
|
||||
d.Online = true
|
||||
d.StreamMode = "TCP-PASSIVE" // 默认UDP传输
|
||||
d.Charset = "GB2312" // 默认GB2312字符集
|
||||
d.GeoCoordSys = "WGS84" // 默认WGS84坐标系
|
||||
d.Transport = req.Transport() // 传输协议
|
||||
d.IP = sourceIP
|
||||
d.Port = sourcePort
|
||||
d.HostAddress = sourceIP + ":" + sourcePortStr
|
||||
d.SipIp = myLanIP
|
||||
d.MediaIp = myWanIP
|
||||
d.Expires = int(expSec)
|
||||
d.eventChan = make(chan any, 10)
|
||||
d.Recipient = sip.Uri{
|
||||
Host: sourceIP,
|
||||
Port: sourcePort,
|
||||
User: deviceid,
|
||||
}
|
||||
d.contactHDR = sip.ContactHeader{
|
||||
Address: sip.Uri{
|
||||
User: gb.Serial,
|
||||
Host: myWanIP,
|
||||
Port: myPort,
|
||||
},
|
||||
}
|
||||
d.fromHDR = sip.FromHeader{
|
||||
Address: sip.Uri{
|
||||
User: gb.Serial,
|
||||
Host: myWanIP,
|
||||
Port: myPort,
|
||||
},
|
||||
Params: sip.NewParams(),
|
||||
}
|
||||
d.plugin = gb
|
||||
d.LocalPort = myPort
|
||||
|
||||
d.Logger = gb.With("deviceid", deviceid)
|
||||
d.fromHDR.Params.Add("tag", sip.GenerateTagN(16))
|
||||
@@ -946,7 +951,7 @@ func (gb *GB28181Plugin) StoreDevice(deviceid string, req *sip.Request) (d *Devi
|
||||
}
|
||||
}
|
||||
})
|
||||
gb.AddTask(d)
|
||||
gb.AddTask(d).WaitStarted()
|
||||
|
||||
if gb.DB != nil {
|
||||
var existing Device
|
||||
@@ -959,7 +964,6 @@ func (gb *GB28181Plugin) StoreDevice(deviceid string, req *sip.Request) (d *Devi
|
||||
gb.Info("StoreDevice", "type", "新增设备", "deviceId", d.DeviceId)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (gb *GB28181Plugin) Pull(streamPath string, conf config.Pull, pubConf *config.Publish) {
|
||||
@@ -976,6 +980,9 @@ func (gb *GB28181Plugin) Pull(streamPath string, conf config.Pull, pubConf *conf
|
||||
dialog.start = conf.Args.Get(util.StartKey)
|
||||
dialog.end = conf.Args.Get(util.EndKey)
|
||||
}
|
||||
if conf.Args.Get("stream") != "" {
|
||||
dialog.stream = conf.Args.Get("stream")
|
||||
}
|
||||
}
|
||||
dialog.GetPullJob().Init(&dialog, &gb.Plugin, streamPath, conf, pubConf)
|
||||
}
|
||||
|
||||
@@ -887,7 +887,7 @@ func (p *Platform) handleDeviceControl(req *sip.Request, tx sip.ServerTransactio
|
||||
ProtocolVersion: "2.0",
|
||||
Transport: device.Transport,
|
||||
Host: device.SipIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
Params: sip.NewParams(),
|
||||
}
|
||||
viaHeader.Params.Add("branch", sip.GenerateBranchN(16)).Add("rport", "")
|
||||
@@ -1345,7 +1345,7 @@ func (p *Platform) handlePresetQuery(req *sip.Request, tx sip.ServerTransaction,
|
||||
ProtocolVersion: "2.0",
|
||||
Transport: device.Transport,
|
||||
Host: device.SipIp,
|
||||
Port: device.localPort,
|
||||
Port: device.LocalPort,
|
||||
Params: sip.NewParams(),
|
||||
}
|
||||
viaHeader.Params.Add("branch", sip.GenerateBranchN(16)).Add("rport", "")
|
||||
|
||||
@@ -2,13 +2,14 @@ package plugin_monitor
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"m7s.live/v5"
|
||||
"m7s.live/v5/pkg/task"
|
||||
"m7s.live/v5/plugin/monitor/pb"
|
||||
monitor "m7s.live/v5/plugin/monitor/pkg"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ = m7s.InstallPlugin[MonitorPlugin](&pb.Api_ServiceDesc, pb.RegisterApiHandler)
|
||||
@@ -65,7 +66,7 @@ func (cfg *MonitorPlugin) OnInit() (err error) {
|
||||
cfg.Plugin.Server.OnBeforeDispose(func() {
|
||||
cfg.saveTask(cfg.Plugin.Server)
|
||||
})
|
||||
cfg.Plugin.Server.OnChildDispose(cfg.saveTask)
|
||||
cfg.Plugin.Server.OnDescendantsDispose(cfg.saveTask)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -371,20 +371,17 @@ func (p *MP4Plugin) StartRecord(ctx context.Context, req *mp4pb.ReqStartRecord)
|
||||
err = pkg.ErrRecordExists
|
||||
return
|
||||
}
|
||||
p.Server.Streams.Call(func() error {
|
||||
if stream, ok := p.Server.Streams.Get(req.StreamPath); ok {
|
||||
recordConf := config.Record{
|
||||
Append: false,
|
||||
Fragment: fragment,
|
||||
FilePath: filePath,
|
||||
}
|
||||
job := p.Record(stream, recordConf, nil)
|
||||
res.Data = uint64(uintptr(unsafe.Pointer(job.GetTask())))
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
if stream, ok := p.Server.Streams.SafeGet(req.StreamPath); ok {
|
||||
recordConf := config.Record{
|
||||
Append: false,
|
||||
Fragment: fragment,
|
||||
FilePath: filePath,
|
||||
}
|
||||
return nil
|
||||
})
|
||||
job := p.Record(stream, recordConf, nil)
|
||||
res.Data = uint64(uintptr(unsafe.Pointer(job.GetTask())))
|
||||
} else {
|
||||
err = pkg.ErrNotFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -432,28 +429,25 @@ func (p *MP4Plugin) EventStart(ctx context.Context, req *mp4pb.ReqEventRecord) (
|
||||
return nil
|
||||
})
|
||||
if tmpJob == nil { //为空表示没有正在进行的录制,也就是没有自动录像,则进行正常的事件录像
|
||||
p.Server.Streams.Call(func() error {
|
||||
if stream, ok := p.Server.Streams.Get(req.StreamPath); ok {
|
||||
recordConf := config.Record{
|
||||
Append: false,
|
||||
Fragment: 0,
|
||||
FilePath: filepath.Join(p.EventRecordFilePath, stream.StreamPath, time.Now().Local().Format("2006-01-02-15-04-05")),
|
||||
}
|
||||
//recordJob := recorder.GetRecordJob()
|
||||
var subconfig config.Subscribe
|
||||
defaults.SetDefaults(&subconfig)
|
||||
subconfig.BufferTime = beforeDuration
|
||||
recordJob := p.Record(stream, recordConf, &subconfig)
|
||||
recordJob.EventId = req.EventId
|
||||
recordJob.EventLevel = req.EventLevel
|
||||
recordJob.EventName = req.EventName
|
||||
recordJob.EventDesc = req.EventDesc
|
||||
recordJob.AfterDuration = afterDuration
|
||||
recordJob.BeforeDuration = beforeDuration
|
||||
recordJob.Mode = m7s.RecordModeEvent
|
||||
if stream, ok := p.Server.Streams.SafeGet(req.StreamPath); ok {
|
||||
recordConf := config.Record{
|
||||
Append: false,
|
||||
Fragment: 0,
|
||||
FilePath: filepath.Join(p.EventRecordFilePath, stream.StreamPath, time.Now().Local().Format("2006-01-02-15-04-05")),
|
||||
}
|
||||
return nil
|
||||
})
|
||||
//recordJob := recorder.GetRecordJob()
|
||||
var subconfig config.Subscribe
|
||||
defaults.SetDefaults(&subconfig)
|
||||
subconfig.BufferTime = beforeDuration
|
||||
recordJob := p.Record(stream, recordConf, &subconfig)
|
||||
recordJob.EventId = req.EventId
|
||||
recordJob.EventLevel = req.EventLevel
|
||||
recordJob.EventName = req.EventName
|
||||
recordJob.EventDesc = req.EventDesc
|
||||
recordJob.AfterDuration = afterDuration
|
||||
recordJob.BeforeDuration = beforeDuration
|
||||
recordJob.Mode = m7s.RecordModeEvent
|
||||
}
|
||||
} else {
|
||||
if tmpJob.AfterDuration != 0 { //当前有事件录像正在录制,则更新该录像的结束时间
|
||||
tmpJob.AfterDuration = time.Duration(tmpJob.Subscriber.VideoReader.AbsTime)*time.Millisecond + afterDuration
|
||||
|
||||
@@ -3,12 +3,13 @@ package rtmp
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"m7s.live/v5/pkg/config"
|
||||
"m7s.live/v5/pkg/task"
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"m7s.live/v5/pkg/config"
|
||||
"m7s.live/v5/pkg/task"
|
||||
|
||||
"m7s.live/v5"
|
||||
)
|
||||
|
||||
@@ -53,7 +54,7 @@ func (c *Client) Start() (err error) {
|
||||
return err
|
||||
}
|
||||
c.Init(conn)
|
||||
c.Logger = c.Logger.With("local", conn.LocalAddr().String())
|
||||
c.SetDescription("local", conn.LocalAddr().String())
|
||||
c.Info("connect")
|
||||
c.WriteChunkSize = c.chunkSize
|
||||
c.AppName = strings.Join(ps[1:len(ps)-1], "/")
|
||||
|
||||
@@ -53,7 +53,7 @@ func (av *Sender) SendFrame(frame *RTMPData) (err error) {
|
||||
// 后面开始,就是直接发送音视频数据,那么直接发送,不需要完整的块(Chunk Basic Header(1) + Chunk Message Header(7))
|
||||
// 当Chunk Type为0时(即Chunk12),
|
||||
if av.lastAbs == 0 {
|
||||
av.SetTimestamp(frame.Timestamp)
|
||||
av.SetTimestamp(1)
|
||||
err = av.sendChunk(frame.Memory.Buffers, &av.ChunkHeader, RTMP_CHUNK_HEAD_12)
|
||||
} else {
|
||||
av.SetTimestamp(frame.Timestamp - av.lastAbs)
|
||||
|
||||
@@ -31,8 +31,8 @@ func (avcc *RTMPVideo) filterH264(naluSizeLen int) {
|
||||
reader := avcc.NewReader()
|
||||
lenReader := reader.NewReader()
|
||||
reader.Skip(5)
|
||||
lenReader.Skip(5)
|
||||
var afterFilter util.Memory
|
||||
lenReader.RangeN(5, afterFilter.AppendOne)
|
||||
allocator := avcc.GetAllocator()
|
||||
var hasBadNalu bool
|
||||
for {
|
||||
@@ -49,7 +49,29 @@ func (avcc *RTMPVideo) filterH264(naluSizeLen int) {
|
||||
reader.RangeN(int(naluLen), func(b []byte) {
|
||||
naluBuffer = append(naluBuffer, b)
|
||||
})
|
||||
if badType := codec.ParseH264NALUType(naluBuffer[0][0]); badType > 9 {
|
||||
badType := codec.ParseH264NALUType(naluBuffer[0][0])
|
||||
// 替换之前打印 badType 的逻辑,解码并打印 SliceType
|
||||
if badType == 5 { // NALU type for Coded slice of a non-IDR picture or Coded slice of an IDR picture
|
||||
naluData := bytes.Join(naluBuffer, nil) // bytes 包已导入
|
||||
if len(naluData) > 0 {
|
||||
// h264parser 包已导入 as "github.com/deepch/vdk/codec/h264parser"
|
||||
// ParseSliceHeaderFromNALU 返回的第一个值就是 SliceType
|
||||
sliceType, err := h264parser.ParseSliceHeaderFromNALU(naluData)
|
||||
if err == nil {
|
||||
println("Decoded SliceType:", sliceType.String())
|
||||
} else {
|
||||
println("Error parsing H.264 slice header:", err.Error())
|
||||
}
|
||||
} else {
|
||||
println("NALU data is empty, cannot parse H.264 slice header.")
|
||||
}
|
||||
}
|
||||
|
||||
switch badType {
|
||||
case 5, 6, 7, 8, 1, 2, 3, 4:
|
||||
afterFilter.Append(lenBuffer...)
|
||||
afterFilter.Append(naluBuffer...)
|
||||
default:
|
||||
hasBadNalu = true
|
||||
if allocator != nil {
|
||||
for _, nalu := range lenBuffer {
|
||||
@@ -59,9 +81,6 @@ func (avcc *RTMPVideo) filterH264(naluSizeLen int) {
|
||||
allocator.Free(nalu)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
afterFilter.Append(lenBuffer...)
|
||||
afterFilter.Append(naluBuffer...)
|
||||
}
|
||||
}
|
||||
if hasBadNalu {
|
||||
@@ -172,7 +191,7 @@ func (avcc *RTMPVideo) Parse(t *AVTrack) (err error) {
|
||||
// case *H265Ctx:
|
||||
// avcc.filterH265(int(ctx.RecordInfo.LengthSizeMinusOne) + 1)
|
||||
// }
|
||||
// if avcc.Size == 0 {
|
||||
// if avcc.Size <= 5 {
|
||||
// return ErrSkip
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -395,18 +395,9 @@ func (c *NetConnection) Receive(sendMode bool, onReceive func(byte, []byte) erro
|
||||
// 如果回调返回错误,检查是否是丢弃错误
|
||||
needToFree = (err != pkg.ErrDiscard)
|
||||
}
|
||||
continue
|
||||
}
|
||||
} else if onRTCP != nil { // 奇数通道,RTCP数据
|
||||
err := onRTCP(channelID, buf)
|
||||
if err == nil {
|
||||
// 如果回调返回nil,表示内存被接管
|
||||
needToFree = false
|
||||
} else {
|
||||
// 如果回调返回错误,检查是否是丢弃错误
|
||||
needToFree = (err != pkg.ErrDiscard)
|
||||
}
|
||||
continue
|
||||
onRTCP(channelID, buf) // 处理RTCP数据,及时释放内存
|
||||
}
|
||||
|
||||
// 如果需要释放内存,则释放
|
||||
|
||||
@@ -47,7 +47,7 @@ func (d *RTSPPullProxy) Start() (err error) {
|
||||
}
|
||||
|
||||
func (d *RTSPPullProxy) Dispose() {
|
||||
if d.conn.NetConnection != nil {
|
||||
if d.conn.NetConnection != nil && d.conn.NetConnection.Conn != nil {
|
||||
_ = d.conn.Teardown()
|
||||
d.conn.NetConnection.Dispose()
|
||||
d.conn.NetConnection = nil
|
||||
|
||||
@@ -369,6 +369,7 @@ func (s *Sender) Send() (err error) {
|
||||
func (r *Receiver) SetMedia(medias []*Media) (err error) {
|
||||
r.AudioChannelID = -1
|
||||
r.VideoChannelID = -1
|
||||
var hasAudio, hasVideo bool // 新增标志位
|
||||
for i, media := range medias {
|
||||
if codec := media.Codecs[0]; codec.IsAudio() {
|
||||
r.AudioCodecParameters = &webrtc.RTPCodecParameters{
|
||||
@@ -382,6 +383,7 @@ func (r *Receiver) SetMedia(medias []*Media) (err error) {
|
||||
PayloadType: webrtc.PayloadType(codec.PayloadType),
|
||||
}
|
||||
r.AudioChannelID = i << 1
|
||||
hasAudio = true // 标记找到音频
|
||||
} else if codec.IsVideo() {
|
||||
r.VideoChannelID = i << 1
|
||||
r.VideoCodecParameters = &webrtc.RTPCodecParameters{
|
||||
@@ -394,10 +396,23 @@ func (r *Receiver) SetMedia(medias []*Media) (err error) {
|
||||
},
|
||||
PayloadType: webrtc.PayloadType(codec.PayloadType),
|
||||
}
|
||||
hasVideo = true // 标记找到视频
|
||||
} else {
|
||||
r.Stream.Warn("media kind not support", "kind", codec.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
// 在遍历后检查,如果 Publisher 存在且未找到对应媒体,则调用 NoAudio/NoVideo
|
||||
if r.Publisher != nil {
|
||||
if !hasAudio {
|
||||
r.Publisher.NoAudio()
|
||||
r.Stream.Info("SDP does not contain audio, calling Publisher.NoAudio()")
|
||||
}
|
||||
if !hasVideo {
|
||||
r.Publisher.NoVideo()
|
||||
r.Stream.Info("SDP does not contain video, calling Publisher.NoVideo()")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package plugin_sei
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
|
||||
globalPB "m7s.live/v5/pb"
|
||||
@@ -38,8 +39,15 @@ func (conf *SEIPlugin) Insert(ctx context.Context, req *pb.InsertRequest) (*glob
|
||||
}).WaitStarted()
|
||||
}
|
||||
t := req.Type
|
||||
|
||||
transformer.AddSEI(byte(t), req.Data)
|
||||
var data []byte
|
||||
switch req.Format {
|
||||
case "json", "string":
|
||||
data = []byte(req.Data)
|
||||
data = []byte(req.Data)
|
||||
case "base64":
|
||||
data, err = base64.StdEncoding.DecodeString(req.Data)
|
||||
}
|
||||
transformer.AddSEI(byte(t), data)
|
||||
err = transformer.WaitStarted()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.19.1
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v5.29.3
|
||||
// source: sei.proto
|
||||
|
||||
package pb
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
pb "m7s.live/v5/pb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,23 +24,21 @@ const (
|
||||
)
|
||||
|
||||
type InsertRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
StreamPath string `protobuf:"bytes,1,opt,name=streamPath,proto3" json:"streamPath,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
|
||||
Type uint32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"`
|
||||
TargetStreamPath string `protobuf:"bytes,4,opt,name=targetStreamPath,proto3" json:"targetStreamPath,omitempty"`
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
StreamPath string `protobuf:"bytes,1,opt,name=streamPath,proto3" json:"streamPath,omitempty"`
|
||||
Data string `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
|
||||
Type uint32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"`
|
||||
TargetStreamPath string `protobuf:"bytes,4,opt,name=targetStreamPath,proto3" json:"targetStreamPath,omitempty"`
|
||||
Format string `protobuf:"bytes,5,opt,name=format,proto3" json:"format,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *InsertRequest) Reset() {
|
||||
*x = InsertRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_sei_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
mi := &file_sei_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *InsertRequest) String() string {
|
||||
@@ -50,7 +49,7 @@ func (*InsertRequest) ProtoMessage() {}
|
||||
|
||||
func (x *InsertRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_sei_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
@@ -72,11 +71,11 @@ func (x *InsertRequest) GetStreamPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *InsertRequest) GetData() []byte {
|
||||
func (x *InsertRequest) GetData() string {
|
||||
if x != nil {
|
||||
return x.Data
|
||||
}
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *InsertRequest) GetType() uint32 {
|
||||
@@ -93,47 +92,43 @@ func (x *InsertRequest) GetTargetStreamPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *InsertRequest) GetFormat() string {
|
||||
if x != nil {
|
||||
return x.Format
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_sei_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_sei_proto_rawDesc = []byte{
|
||||
0x0a, 0x09, 0x73, 0x65, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x73, 0x65, 0x69,
|
||||
0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e,
|
||||
0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c,
|
||||
0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x01, 0x0a,
|
||||
0x0d, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1e,
|
||||
0x0a, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61,
|
||||
0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
|
||||
0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
|
||||
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x10, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x61,
|
||||
0x74, 0x68, 0x32, 0x6b, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x12, 0x64, 0x0a, 0x06, 0x69, 0x6e, 0x73,
|
||||
0x65, 0x72, 0x74, 0x12, 0x12, 0x2e, 0x73, 0x65, 0x69, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c,
|
||||
0x2e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x22, 0x1f, 0x2f, 0x73, 0x65, 0x69, 0x2f, 0x61,
|
||||
0x70, 0x69, 0x2f, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x2f, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61,
|
||||
0x6d, 0x50, 0x61, 0x74, 0x68, 0x3d, 0x2a, 0x2a, 0x7d, 0x3a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42,
|
||||
0x1f, 0x5a, 0x1d, 0x6d, 0x37, 0x73, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2f, 0x6d, 0x37, 0x73, 0x2f,
|
||||
0x76, 0x35, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x73, 0x65, 0x69, 0x2f, 0x70, 0x62,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
const file_sei_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\tsei.proto\x12\x03sei\x1a\x1cgoogle/api/annotations.proto\x1a\fglobal.proto\"\x9b\x01\n" +
|
||||
"\rInsertRequest\x12\x1e\n" +
|
||||
"\n" +
|
||||
"streamPath\x18\x01 \x01(\tR\n" +
|
||||
"streamPath\x12\x12\n" +
|
||||
"\x04data\x18\x02 \x01(\tR\x04data\x12\x12\n" +
|
||||
"\x04type\x18\x03 \x01(\rR\x04type\x12*\n" +
|
||||
"\x10targetStreamPath\x18\x04 \x01(\tR\x10targetStreamPath\x12\x16\n" +
|
||||
"\x06format\x18\x05 \x01(\tR\x06format2k\n" +
|
||||
"\x03api\x12d\n" +
|
||||
"\x06insert\x12\x12.sei.InsertRequest\x1a\x17.global.SuccessResponse\"-\x82\xd3\xe4\x93\x02':\x04data\"\x1f/sei/api/insert/{streamPath=**}B\x1bZ\x19m7s.live/v5/plugin/sei/pbb\x06proto3"
|
||||
|
||||
var (
|
||||
file_sei_proto_rawDescOnce sync.Once
|
||||
file_sei_proto_rawDescData = file_sei_proto_rawDesc
|
||||
file_sei_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_sei_proto_rawDescGZIP() []byte {
|
||||
file_sei_proto_rawDescOnce.Do(func() {
|
||||
file_sei_proto_rawDescData = protoimpl.X.CompressGZIP(file_sei_proto_rawDescData)
|
||||
file_sei_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_sei_proto_rawDesc), len(file_sei_proto_rawDesc)))
|
||||
})
|
||||
return file_sei_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_sei_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_sei_proto_goTypes = []interface{}{
|
||||
var file_sei_proto_goTypes = []any{
|
||||
(*InsertRequest)(nil), // 0: sei.InsertRequest
|
||||
(*pb.SuccessResponse)(nil), // 1: global.SuccessResponse
|
||||
}
|
||||
@@ -152,25 +147,11 @@ func file_sei_proto_init() {
|
||||
if File_sei_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_sei_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*InsertRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_sei_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_sei_proto_rawDesc), len(file_sei_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
@@ -181,7 +162,6 @@ func file_sei_proto_init() {
|
||||
MessageInfos: file_sei_proto_msgTypes,
|
||||
}.Build()
|
||||
File_sei_proto = out.File
|
||||
file_sei_proto_rawDesc = nil
|
||||
file_sei_proto_goTypes = nil
|
||||
file_sei_proto_depIdxs = nil
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ service api {
|
||||
|
||||
message InsertRequest {
|
||||
string streamPath = 1;
|
||||
bytes data = 2;
|
||||
string data = 2;
|
||||
uint32 type = 3;
|
||||
string targetStreamPath = 4;
|
||||
string format = 5;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.19.1
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v5.29.3
|
||||
// source: sei.proto
|
||||
|
||||
package pb
|
||||
@@ -16,8 +16,12 @@ import (
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.32.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion7
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
Api_Insert_FullMethodName = "/sei.api/insert"
|
||||
)
|
||||
|
||||
// ApiClient is the client API for Api service.
|
||||
//
|
||||
@@ -35,8 +39,9 @@ func NewApiClient(cc grpc.ClientConnInterface) ApiClient {
|
||||
}
|
||||
|
||||
func (c *apiClient) Insert(ctx context.Context, in *InsertRequest, opts ...grpc.CallOption) (*pb.SuccessResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(pb.SuccessResponse)
|
||||
err := c.cc.Invoke(ctx, "/sei.api/insert", in, out, opts...)
|
||||
err := c.cc.Invoke(ctx, Api_Insert_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -45,20 +50,24 @@ func (c *apiClient) Insert(ctx context.Context, in *InsertRequest, opts ...grpc.
|
||||
|
||||
// ApiServer is the server API for Api service.
|
||||
// All implementations must embed UnimplementedApiServer
|
||||
// for forward compatibility
|
||||
// for forward compatibility.
|
||||
type ApiServer interface {
|
||||
Insert(context.Context, *InsertRequest) (*pb.SuccessResponse, error)
|
||||
mustEmbedUnimplementedApiServer()
|
||||
}
|
||||
|
||||
// UnimplementedApiServer must be embedded to have forward compatible implementations.
|
||||
type UnimplementedApiServer struct {
|
||||
}
|
||||
// UnimplementedApiServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedApiServer struct{}
|
||||
|
||||
func (UnimplementedApiServer) Insert(context.Context, *InsertRequest) (*pb.SuccessResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Insert not implemented")
|
||||
}
|
||||
func (UnimplementedApiServer) mustEmbedUnimplementedApiServer() {}
|
||||
func (UnimplementedApiServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeApiServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to ApiServer will
|
||||
@@ -68,6 +77,13 @@ type UnsafeApiServer interface {
|
||||
}
|
||||
|
||||
func RegisterApiServer(s grpc.ServiceRegistrar, srv ApiServer) {
|
||||
// If the following call pancis, it indicates UnimplementedApiServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&Api_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
@@ -81,7 +97,7 @@ func _Api_Insert_Handler(srv interface{}, ctx context.Context, dec func(interfac
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/sei.api/insert",
|
||||
FullMethod: Api_Insert_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApiServer).Insert(ctx, req.(*InsertRequest))
|
||||
|
||||
27
puller.go
27
puller.go
@@ -122,6 +122,33 @@ func (p *PullJob) Init(puller IPuller, plugin *Plugin, streamPath string, conf c
|
||||
"maxRetry": conf.MaxRetry,
|
||||
})
|
||||
puller.SetRetry(conf.MaxRetry, conf.RetryInterval)
|
||||
|
||||
if sender := plugin.getHookSender(config.HookOnPullStart); sender != nil {
|
||||
puller.OnStart(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnPullStart,
|
||||
"streamPath": streamPath,
|
||||
"url": conf.URL,
|
||||
"args": conf.Args,
|
||||
"pluginName": plugin.Meta.Name,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnPullStart, webhookData)
|
||||
})
|
||||
}
|
||||
|
||||
if sender := plugin.getHookSender(config.HookOnPullEnd); sender != nil {
|
||||
puller.OnDispose(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnPullEnd,
|
||||
"streamPath": streamPath,
|
||||
"reason": puller.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnPullEnd, webhookData)
|
||||
})
|
||||
}
|
||||
|
||||
plugin.Server.Pulls.Add(p, plugin.Logger.With("pullURL", conf.URL, "streamPath", streamPath))
|
||||
return p
|
||||
}
|
||||
|
||||
25
pusher.go
25
pusher.go
@@ -2,6 +2,7 @@ package m7s
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"m7s.live/v5/pkg"
|
||||
"m7s.live/v5/pkg/task"
|
||||
@@ -43,6 +44,30 @@ func (p *PushJob) Init(pusher IPusher, plugin *Plugin, streamPath string, conf c
|
||||
"maxRetry": conf.MaxRetry,
|
||||
})
|
||||
pusher.SetRetry(conf.MaxRetry, conf.RetryInterval)
|
||||
if sender := plugin.getHookSender(config.HookOnPushStart); sender != nil {
|
||||
pusher.OnStart(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnPullStart,
|
||||
"streamPath": streamPath,
|
||||
"url": conf.URL,
|
||||
"pluginName": plugin.Meta.Name,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnPullStart, webhookData)
|
||||
})
|
||||
}
|
||||
|
||||
if sender := plugin.getHookSender(config.HookOnPushEnd); sender != nil {
|
||||
pusher.OnDispose(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnPullEnd,
|
||||
"streamPath": streamPath,
|
||||
"reason": pusher.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnPullEnd, webhookData)
|
||||
})
|
||||
}
|
||||
plugin.Server.Pushs.Add(p, plugin.Logger.With("pushURL", conf.URL, "streamPath", streamPath))
|
||||
return p
|
||||
}
|
||||
|
||||
26
recoder.go
26
recoder.go
@@ -103,6 +103,32 @@ func (p *RecordJob) Init(recorder IRecorder, plugin *Plugin, streamPath string,
|
||||
"fragment": conf.Fragment,
|
||||
})
|
||||
recorder.SetRetry(-1, time.Second)
|
||||
if sender := plugin.getHookSender(config.HookOnRecordStart); sender != nil {
|
||||
recorder.OnStart(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnRecordStart,
|
||||
"streamPath": streamPath,
|
||||
"filePath": conf.FilePath,
|
||||
"pluginName": plugin.Meta.Name,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnRecordStart, webhookData)
|
||||
})
|
||||
}
|
||||
|
||||
if sender := plugin.getHookSender(config.HookOnRecordEnd); sender != nil {
|
||||
recorder.OnDispose(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnRecordEnd,
|
||||
"streamPath": streamPath,
|
||||
"filePath": conf.FilePath,
|
||||
"reason": recorder.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnRecordEnd, webhookData)
|
||||
})
|
||||
}
|
||||
|
||||
plugin.Server.Records.Add(p, plugin.Logger.With("filePath", conf.FilePath, "streamPath", streamPath))
|
||||
return p
|
||||
}
|
||||
|
||||
@@ -105,6 +105,28 @@ func (p *TransformJob) Init(transformer ITransformer, plugin *Plugin, pub *Publi
|
||||
"conf": conf,
|
||||
})
|
||||
transformer.SetRetry(-1, time.Second*2)
|
||||
if sender := plugin.getHookSender(config.HookOnTransformStart); sender != nil {
|
||||
transformer.OnStart(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnTransformStart,
|
||||
"streamPath": pub.StreamPath,
|
||||
"pluginName": plugin.Meta.Name,
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnTransformStart, webhookData)
|
||||
})
|
||||
}
|
||||
if sender := plugin.getHookSender(config.HookOnTransformEnd); sender != nil {
|
||||
transformer.OnDispose(func() {
|
||||
webhookData := map[string]interface{}{
|
||||
"event": config.HookOnTransformEnd,
|
||||
"streamPath": pub.StreamPath,
|
||||
"reason": transformer.StopReason().Error(),
|
||||
"timestamp": time.Now().Unix(),
|
||||
}
|
||||
sender(config.HookOnTransformEnd, webhookData)
|
||||
})
|
||||
}
|
||||
plugin.Server.Transforms.AddTask(p, plugin.Logger.With("streamPath", pub.StreamPath))
|
||||
return p
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user