client

package
v1.6.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2026 License: GPL-3.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultByeTimeout = 15 * time.Second // 单次 BYE 等待响应超时(与底层 GetResponse 的 ~15s 对齐)
	DefaultByeRetry   = 2                // BYE 无响应时的重试次数(总尝试次数 = 重试次数 + 1)
)

BYE 终止旧推流时的超时与重试策略。

设计依据:GB28181 设备对 BYE 的响应可能因网络抖动或实现差异而延迟甚至丢失。 单次等待过短会误判失败,过长会阻塞新 INVITE;故采用「短超时 + 重试」策略, 重试耗尽后强制清理本地会话状态,确保新 INVITE 可正常发出,避免多 SSRC 并存。

View Source
const FFMPEG_TO_FLV = "FFmpeg to FLV"
View Source
const REGIST_STATUS_FATIL = "0"
View Source
const REGIST_STATUS_OK = "1"
View Source
const SIP_STATUS_OFF = "OFF"
View Source
const SIP_STATUS_ON = "ON"

Variables

This section is empty.

Functions

This section is empty.

Types

type SessionManager added in v1.6.9

type SessionManager struct {
	// contains filtered or unexported fields
}

SessionManager 管理所有活跃推流会话,解决 GB28181 设备重推未停旧流导致的多 SSRC 并存问题。

维护两张索引:

  1. sessions: StreamPath -> StreamSession
  2. ssrcIdx : SSRC -> StreamPath(用于 SSRC 冲突检测)

func NewSessionManager added in v1.6.9

func NewSessionManager() *SessionManager

NewSessionManager 创建会话管理器

func (*SessionManager) AllSessions added in v1.6.9

func (m *SessionManager) AllSessions() []*StreamSession

AllSessions 返回所有会话的快照(用于诊断/监控)

func (*SessionManager) Count added in v1.6.9

func (m *SessionManager) Count() int

Count 返回当前活跃会话数

func (*SessionManager) DetectConflict added in v1.6.9

func (m *SessionManager) DetectConflict(streamPath, ssrc string) (conflictPath string)

DetectConflict 检测给定 SSRC 是否与现存会话冲突: 若该 SSRC 已属于其他 StreamPath,则返回冲突的 StreamPath。

func (*SessionManager) FindBySSRC added in v1.6.9

func (m *SessionManager) FindBySSRC(ssrc string) (streamPath string, ok bool)

FindBySSRC 根据 SSRC 查找所属 StreamPath(冲突检测用)

func (*SessionManager) GetSession added in v1.6.9

func (m *SessionManager) GetSession(streamPath string) *StreamSession

GetSession 根据 StreamPath 获取会话(线程安全)

func (*SessionManager) LockSession added in v1.6.9

func (m *SessionManager) LockSession(streamPath string) *StreamSession

LockSession 锁定指定会话以串行化操作,返回会话指针。 若会话不存在返回 nil。调用方应 defer Unlock()。

func (*SessionManager) RegisterSession added in v1.6.9

func (m *SessionManager) RegisterSession(s *StreamSession)

RegisterSession 注册新会话并建立 SSRC 索引。 若同一 StreamPath 已存在旧会话,先清理旧会话的 SSRC 索引。 注意:调用方应在此之前完成旧会话的 BYE 拆除。

func (*SessionManager) RemoveSession added in v1.6.9

func (m *SessionManager) RemoveSession(streamPath string) *StreamSession

RemoveSession 移除会话及其 SSRC 索引,返回被移除的会话(便于上层做收尾日志)

func (*SessionManager) UpdateSSRC added in v1.6.9

func (m *SessionManager) UpdateSSRC(streamPath, newSSRC string) (oldSSRC string, changed bool)

UpdateSSRC 更新会话的 SSRC(设备因网络抖动以新 SSRC 重启推流时调用)。 返回旧 SSRC 与是否发生了变化。同时维护 ssrcIdx 一致性。

type SessionStatus added in v1.6.9

type SessionStatus int

SessionStatus 表示一路推流会话的当前状态

const (
	SessionStatusActive      SessionStatus = 1 // 会话已建立,推流进行中
	SessionStatusTerminating SessionStatus = 2 // 正在发送 BYE 终止旧推流
	SessionStatusTerminated  SessionStatus = 3 // 会话已终止
)

func (SessionStatus) String added in v1.6.9

func (s SessionStatus) String() string

type SipClient

type SipClient struct {
	*transaction.Core `json:"-"`
	ID                string

	LocalIp string

	RegisterTime    time.Time
	UpdateTime      time.Time
	LastKeepaliveAt time.Time
	TryCnt          uint
	Done            chan struct{}
	MinPort         uint16
	MaxPort         uint16
	Status          string
	Timer           int

	LogPrint func(code int, msg string)
	// contains filtered or unexported fields
}

func NewClient

func NewClient(config *transaction.Config) (*SipClient, error)

func (*SipClient) CreateMessage added in v1.1.3

func (c *SipClient) CreateMessage(mehod sip.Method, body string) *sip.Message

func (*SipClient) SetUp

func (c *SipClient) SetUp(handle SipHandleFunc) error

func (*SipClient) UnRegister added in v1.2.5

func (c *SipClient) UnRegister()

type SipHandleFunc added in v1.1.2

type SipHandleFunc interface {
	HandleRegister(req *sip.Request, tx *transaction.GBTx)
	HandleInvite(req *sip.Request, tx *transaction.GBTx)
	HandleMessage(req *sip.Request, tx *transaction.GBTx)
	HandleAck(req *sip.Request, tx *transaction.GBTx)
	HandleByte(req *sip.Request, tx *transaction.GBTx)
	HandleSubsribe(req *sip.Request, tx *transaction.GBTx)
	KeepLiveCall(deviceId, status string)
	RegisterCall(deviceId, status string)
}

type SipServer added in v1.1.6

type SipServer struct {
	*transaction.Core `json:"-"`

	// LogPrint 关键节点日志输出,便于问题排查
	LogPrint func(code int, msg string)
	// contains filtered or unexported fields
}

func NewServer added in v1.1.6

func NewServer(config *transaction.Config) (*SipServer, error)

func (*SipServer) SessionSummary added in v1.6.9

func (c *SipServer) SessionSummary() string

SessionSummary 返回所有活跃会话的摘要信息,用于诊断与监控(非业务必需)。

func (*SipServer) Sessions added in v1.6.9

func (c *SipServer) Sessions() *SessionManager

Sessions 返回会话管理器,供上层进行会话诊断与监控

func (*SipServer) SetUp added in v1.1.6

func (c *SipServer) SetUp(handle SipServerHandleFunc) error

func (*SipServer) SipRequestForResponse added in v1.6.9

func (c *SipServer) SipRequestForResponse(req *sip.Request) (*sip.Response, error)

SipRequestForResponse 影子覆盖 Core.SipRequestForResponse,对 INVITE/BYE 自动进行会话管理。

这是「闭环」处理 SSRC 问题的核心入口:业务系统仍按原方式调用 `server.SipRequestForResponse(req)` 发送 INVITE/BYE,无需任何改动。 本方法在内部透明地完成:

  • INVITE:先对同设备的旧会话发送 BYE(含超时重试),再发送新 INVITE,200 OK 后注册会话
  • BYE :发送后从会话管理器移除对应会话
  • 其它 :直接委托给 Core 处理

通过按「目标设备 ID」键会话,服务端重复 INVITE 同一设备时自动拆除旧推流, 从信令层根除多 SSRC 并存问题。

type SipServerHandleFunc added in v1.1.6

type SipServerHandleFunc interface {
	HandleRegister(req *sip.Request, tx *transaction.GBTx)
	HandleInvite(req *sip.Request, tx *transaction.GBTx)
	HandleMessage(req *sip.Request, tx *transaction.GBTx)
	HandleAck(req *sip.Request, tx *transaction.GBTx)
	HandleNotify(req *sip.Request, tx *transaction.GBTx)
	HandleByte(req *sip.Request, tx *transaction.GBTx)
}

type StreamSession added in v1.6.9

type StreamSession struct {
	StreamPath string // 流路径,如 "deviceID/channelID",作为会话唯一键

	// dialog 标识:BYE 必须复用以下字段,否则设备无法匹配到原会话
	CallID  string  // INVITE 的 Call-ID
	FromTag string  // 本端 From tag(INVITE 时生成)
	ToTag   string  // 对端 To tag(来自设备 200 OK 响应)
	FromUri sip.URI // From URI(本端)
	ToUri   sip.URI // To URI(对端设备 URI)

	// 远端目标:BYE 的 Request-URI 取自 200 OK 的 Contact 头域;
	// 若 Contact 缺失,则回退到 ToUri
	RemoteTarget sip.URI
	// 设备信令地址(200 OK 的来源地址),作为 BYE 发送目标
	RemoteAddr net.Addr
	LocalAddr  net.Addr

	SSRC string // SDP 中 y= 字段的 SSRC 值,用于冲突检测

	CSeq uint32 // 当前 dialog 内最新 CSeq,BYE 需在其基础上递增

	Status    SessionStatus
	CreatedAt time.Time
	UpdatedAt time.Time
	// contains filtered or unexported fields
}

StreamSession 记录一路 GB28181 推流会话(SIP dialog)的完整状态。

背景:原实现仅按 CallID 维护 transaction,没有 dialog 级别的会话管理。 当设备重连、流类型切换等场景触发新的 INVITE 时,旧推流未通过 BYE 停止, 设备同时维持两路 RTP 推流(不同 SSRC),导致业务侧 "RTP SSRC切换,重置解码器"。 本结构在 INVITE 200 OK 后捕获 dialog 标识,供后续 BYE 复用,确保旧流被正确拆除。

func (*StreamSession) String added in v1.6.9

func (s *StreamSession) String() string

String 用于日志输出会话摘要

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL