mirror of
https://github.com/hackdiaz-dev/free-turn-proxy.git
synced 2026-10-12 09:41:53 +02:00
86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package mobile
|
|
|
|
import (
|
|
"fmt"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/samosvalishe/free-turn-proxy/internal/logx"
|
|
"github.com/samosvalishe/free-turn-proxy/internal/session"
|
|
)
|
|
|
|
const (
|
|
LevelDebug = "debug"
|
|
LevelInfo = "info"
|
|
LevelWarn = "warn"
|
|
LevelError = "error"
|
|
)
|
|
|
|
// EventSink - приёмник событий сессии, реализуемый хостом (Java/ObjC).
|
|
// OnLog может вызываться конкурентно; методы не должны блокировать исполнение.
|
|
type EventSink interface {
|
|
OnState(state string, streams, total int, errMsg string)
|
|
OnLog(level, msg string, unixMillis int64)
|
|
// OnCaptcha передаёт URL для решения капчи вручную (пустой url - закрыть окно).
|
|
OnCaptcha(url string)
|
|
}
|
|
|
|
var sink atomic.Pointer[EventSink]
|
|
|
|
// SetEventSink регистрирует приёмник событий (nil отключает push-канал).
|
|
func SetEventSink(s EventSink) {
|
|
if s == nil {
|
|
sink.Store(nil)
|
|
return
|
|
}
|
|
sink.Store(&s)
|
|
}
|
|
|
|
func currentSink() EventSink {
|
|
if p := sink.Load(); p != nil {
|
|
return *p
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func emitCaptcha(url string) {
|
|
if s := currentSink(); s != nil {
|
|
s.OnCaptcha(url)
|
|
}
|
|
}
|
|
|
|
type observer struct{}
|
|
|
|
func (observer) OnPhase(phase session.Phase, streams, total int, errMsg string) {
|
|
if s := currentSink(); s != nil {
|
|
s.OnState(string(phase), streams, total, errMsg)
|
|
}
|
|
}
|
|
|
|
func coreLog() logx.Logger { return &sinkLogger{buf: sharedLogBuf} }
|
|
|
|
// sinkLogger дублирует логи в кольцевой буфер и EventSink.
|
|
type sinkLogger struct {
|
|
debug bool
|
|
buf *logBuffer
|
|
}
|
|
|
|
func (l *sinkLogger) write(level, format string, v ...any) {
|
|
msg := fmt.Sprintf(format, v...)
|
|
now := time.Now()
|
|
l.buf.append(now.Format("15:04:05") + " [" + level + "] " + msg)
|
|
if s := currentSink(); s != nil {
|
|
s.OnLog(level, msg, now.UnixMilli())
|
|
}
|
|
}
|
|
|
|
func (l *sinkLogger) Debugf(format string, v ...any) {
|
|
if l.debug {
|
|
l.write(LevelDebug, format, v...)
|
|
}
|
|
}
|
|
func (l *sinkLogger) Infof(format string, v ...any) { l.write(LevelInfo, format, v...) }
|
|
func (l *sinkLogger) Warnf(format string, v ...any) { l.write(LevelWarn, format, v...) }
|
|
func (l *sinkLogger) Errorf(format string, v ...any) { l.write(LevelError, format, v...) }
|
|
func (l *sinkLogger) DebugEnabled() bool { return l.debug }
|