Documentation
¶
Index ¶
- Constants
- type SessionManager
- func (m *SessionManager) AllSessions() []*StreamSession
- func (m *SessionManager) Count() int
- func (m *SessionManager) DetectConflict(streamPath, ssrc string) (conflictPath string)
- func (m *SessionManager) FindBySSRC(ssrc string) (streamPath string, ok bool)
- func (m *SessionManager) GetSession(streamPath string) *StreamSession
- func (m *SessionManager) LockSession(streamPath string) *StreamSession
- func (m *SessionManager) RegisterSession(s *StreamSession)
- func (m *SessionManager) RemoveSession(streamPath string) *StreamSession
- func (m *SessionManager) UpdateSSRC(streamPath, newSSRC string) (oldSSRC string, changed bool)
- type SessionStatus
- type SipClient
- type SipHandleFunc
- type SipServer
- type SipServerHandleFunc
- type StreamSession
Constants ¶
const ( DefaultByeTimeout = 15 * time.Second // 单次 BYE 等待响应超时(与底层 GetResponse 的 ~15s 对齐) DefaultByeRetry = 2 // BYE 无响应时的重试次数(总尝试次数 = 重试次数 + 1) )
BYE 终止旧推流时的超时与重试策略。
设计依据:GB28181 设备对 BYE 的响应可能因网络抖动或实现差异而延迟甚至丢失。 单次等待过短会误判失败,过长会阻塞新 INVITE;故采用「短超时 + 重试」策略, 重试耗尽后强制清理本地会话状态,确保新 INVITE 可正常发出,避免多 SSRC 并存。
const FFMPEG_TO_FLV = "FFmpeg to FLV"
const REGIST_STATUS_FATIL = "0"
const REGIST_STATUS_OK = "1"
const SIP_STATUS_OFF = "OFF"
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 并存问题。
维护两张索引:
- sessions: StreamPath -> StreamSession
- 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) 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 (*SipClient) CreateMessage ¶ added in v1.1.3
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 (*SipServer) SessionSummary ¶ added in v1.6.9
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
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 用于日志输出会话摘要