transaction

package
v3.0.1 Latest Latest
Warning

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

Go to latest
Published: Dec 22, 2021 License: AGPL-3.0 Imports: 9 Imported by: 0

README

事物

transaction事务是SIP的基本组成部分。 一个事务是客户发送的一个请求事务(通过通讯层)发送到一个服务器事务,连同服务器事务的所有的该请求的应答发送回客户端事务。 事务层处理应用服务层的重发,匹配请求的应答,以及应用服务层的超时。 任何一个用户代理客户端(user agent client UAC)完成的事情都是由一组事务构成的。 用户代理包含一个事务层,来实现有状态的代理服务器。 事务层包含一个客户元素(可以认为是一个客户事务)和一个服务器元素(可以认为是一个服务器事务),他们都可以用一个有限状态机来处理特定的请求。

在状态机层面,事物分为ict、ist、nict、nist四种。 但底层事物方面,仅根据 method 等信息,分支处理。

关于事物管理

事物在map里面管理,事物ID的选择是要和事物匹配相关。

客户端事件的匹配

当客户端中的传输层收到响应时,它必须确定哪个客户端事务将处理该响应,以便可以进行17.1.1和17.1.2节的处理。头域 Via 字段中的branch参数用于匹配规则。 一个匹配的响应应该满足下面两个条件:
1.如果响应的头域 Via头字段中的branch参数值与创建事务的请求的头域 Via头字段中的branch参数值相同。
2.如果CSeq标头字段中的method参数与创建事务的请求的方法匹配。(由于CANCEL请求会创建新的事务,但共享相同的branch参数值。所以仅用branch参数是不够的)


服务端事物匹配

首先要检查请求中的Via头域的branch参数。如果他以”z9hG4bk”开头,那么这个请求一定是由客户端事务根据本规范产生的。因此,branch参数在该客户端发出的所有的事务中都是唯一的。根据下列规则我们可以判定请求是否和事务匹配:

1、 请求的Via头域的branch参数和创建本事务的请求的Via头域的branch参数一样,并且:
2、 请求的Via头域的send-by参数和创建本事务的请求的Via头域的send-by参数一样(可能存在来自不同客户端的branch参数的意外或恶意重复,所以将 send-by 值用作匹配的一部分),并且:
3、 请求的方法与创建事务的方法匹配,但ACK除外,在ACK中,创建事务的请求的方法为INVITE。

所以,根据匹配规则,事物的ID 使用 branch,然后在匹配逻辑里面,再做条件判断。而因为branch可能会重复,所以如果使用map来简化transaction的管理,key的取值应该:

客户端事物: branch+method 服务端事物: branch + sendby + method,method中ack还要除外。所以只能用branch + sendby

Documentation

Index

Constants

View Source
const (
	T1      = 100 * time.Millisecond
	T2      = 4 * time.Second
	T4      = 5 * time.Second
	TimeA   = T1
	TimeB   = 64 * T1
	TimeD   = 32 * time.Second
	TimeE   = T1
	TimeF   = 64 * T1
	TimeG   = T1
	TimeH   = 64 * T1
	TimeI   = T4
	TimeJ   = 64 * T1
	TimeK   = T4
	Time1xx = 100 * time.Millisecond
)

timer相关基础常量、方法等定义

Variables

View Source
var (
	ErrorSyntax  = errors.New("message syntax error")
	ErrorCheck   = errors.New("message check failed")
	ErrorParse   = errors.New("message parse failed")
	ErrorUnknown = errors.New("message unknown")
)

transaction 的错误定义

Functions

This section is empty.

Types

type Config

type Config struct {
	//sip服务器的配置
	SipNetwork string //传输协议,默认UDP,可选TCP
	SipIP      string //sip 服务器公网IP
	SipPort    uint16 //sip 服务器端口,默认 5060
	Serial     string //sip 服务器 id, 默认 34020000002000000001
	Realm      string //sip 服务器域,默认 3402000000
	Username   string //sip 服务器账号
	Password   string //sip 服务器密码

	AckTimeout        uint16 //sip 服务应答超时,单位秒
	RegisterValidity  int    //注册有效期,单位秒,默认 3600
	RegisterInterval  int    //注册间隔,单位秒,默认 60
	HeartbeatInterval int    //心跳间隔,单位秒,默认 60
	HeartbeatRetry    int    //心跳超时次数,默认 3

	//媒体服务器配置
	MediaIP           string //媒体服务器地址
	MediaPort         uint16 //媒体服务器端口
	MediaPortMin      uint16
	MediaPortMax      uint16
	MediaIdleTimeout  uint16 //推流超时时间,超过则断开链接,让设备重连
	AudioEnable       bool   //是否开启音频
	WaitKeyFrame      bool   //是否等待关键帧,如果等待,则在收到第一个关键帧之前,忽略所有媒体流
	RemoveBanInterval int    //移除禁止设备间隔
	UdpCacheSize      int    //udp缓存大小
}

type Core

type Core struct {
	*Config    //sip server配置信息
	OnRegister func(*sip.Message)
	OnMessage  func(*sip.Message) bool
	// contains filtered or unexported fields
}

Core: transactions manager 管理所有 transactions,以及相关全局参数、运行状态机

func NewCore

func NewCore(config *Config) *Core

初始化一个 Core,需要能响应请求,也要能发起请求 client 发起请求 server 响应请求 TODO:根据角色,增加相关配置信息 TODO:通过context管理子线程 TODO:单元测试

func (*Core) AddTransaction

func (c *Core) AddTransaction(ta *Transaction)

add transaction to core

func (*Core) DelTransaction

func (c *Core) DelTransaction(tid string)

delete transaction

func (*Core) HandleReceiveMessage

func (c *Core) HandleReceiveMessage(p *transport.Packet) (err error)

接收到的消息处理 收到消息有两种:1、请求消息 2、响应消息 请求消息则直接响应处理。 响应消息则需要匹配到请求,让请求的transaction来处理。 TODO:参考srs和osip的流程,以及文档,做最终处理。需要将逻辑分成两层:TU 层和 transaction 层

func (*Core) Handler

func (c *Core) Handler()

func (*Core) Send

func (c *Core) Send(msg *sip.Message) error

func (*Core) SendMessage

func (c *Core) SendMessage(msg *sip.Message) *Response

发送消息:发送请求或者响应 发送消息仅负责发送。报错有两种:1、发送错误。2、发送了但是超时没有收到响应 如果发送成功,如何判断是否收到响应?没有收到响应要重传 所以一个transaction 有read和wriet的chan。 发送的时候写 write chan 接收的时候读取 read chan 发送之后,就开启timer,超时重传,还要记录和修改每次超时时间。不超时的话,记得删掉timer 发送 register 消息

func (*Core) Start

func (c *Core) Start()

type Event

type Event int

状态机之事件

const (
	/* TIMEOUT EVENTS for ICT */
	TIMEOUT_A Event = iota /**< Timer A */
	TIMEOUT_B              /**< Timer B */
	TIMEOUT_D              /**< Timer D */

	/* TIMEOUT EVENTS for NICT */
	TIMEOUT_E /**< Timer E */
	TIMEOUT_F /**< Timer F */
	TIMEOUT_K /**< Timer K */

	/* TIMEOUT EVENTS for IST */
	TIMEOUT_G /**< Timer G */
	TIMEOUT_H /**< Timer H */
	TIMEOUT_I /**< Timer I */

	/* TIMEOUT EVENTS for NIST */
	TIMEOUT_J /**< Timer J */

	/* FOR INCOMING MESSAGE */
	RCV_REQINVITE     /**< Event is an incoming INVITE request */
	RCV_REQACK        /**< Event is an incoming ACK request */
	RCV_REQUEST       /**< Event is an incoming NON-INVITE and NON-ACK request */
	RCV_STATUS_1XX    /**< Event is an incoming informational response */
	RCV_STATUS_2XX    /**< Event is an incoming 2XX response */
	RCV_STATUS_3456XX /**< Event is an incoming final response (not 2XX) */

	/* FOR OUTGOING MESSAGE */
	SND_REQINVITE     /**< Event is an outgoing INVITE request */
	SND_REQACK        /**< Event is an outgoing ACK request */
	SND_REQUEST       /**< Event is an outgoing NON-INVITE and NON-ACK request */
	SND_STATUS_1XX    /**< Event is an outgoing informational response */
	SND_STATUS_2XX    /**< Event is an outgoing 2XX response */
	SND_STATUS_3456XX /**< Event is an outgoing final response (not 2XX) */

	KILL_TRANSACTION /**< Event to 'kill' the transaction before termination */
	UNKNOWN_EVT      /**< Max event */
)

func (Event) IsIncomingMessage

func (e Event) IsIncomingMessage() bool

incoming SIP MESSAGE

func (Event) IsIncomingRequest

func (e Event) IsIncomingRequest() bool

incoming SIP REQUEST

func (Event) IsIncomingResponse

func (e Event) IsIncomingResponse() bool

incoming SIP RESPONSE

func (Event) IsOutgoingMessage

func (e Event) IsOutgoingMessage() bool

outgoing SIP MESSAGE

func (Event) IsOutgoingRequest

func (e Event) IsOutgoingRequest() bool

outgoing SIP REQUEST

func (Event) IsOutgoingResponse

func (e Event) IsOutgoingResponse() bool

outgoing SIP RESPONSE

func (Event) IsSipMessage

func (e Event) IsSipMessage() bool

a SIP MESSAGE

func (Event) String

func (e Event) String() string

type EventObj

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

type FSMType

type FSMType int

状态机类型

const (
	FSM_ICT     FSMType = iota /**< Invite Client (outgoing) Transaction */
	FSM_IST                    /**< Invite Server (incoming) Transaction */
	FSM_NICT                   /**< Non-Invite Client (outgoing) Transaction */
	FSM_NIST                   /**< Non-Invite Server (incoming) Transaction */
	FSM_UNKNOWN                /**< Invalid Transaction */
)

func (FSMType) String

func (t FSMType) String() string

type Handler

type Handler func(*Transaction, Event, *sip.Message) error //操作
type Header map[string]string

type Request

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

对外将sip通讯封装成请求和响应 TODO:可参考http的request和response,屏蔽sip协议细节

type Response

type Response struct {
	Code    int
	Message string
	Data    *sip.Message
}

Code = 0,则响应正常 Code != 0,打印错误提示信息 Message

type SipTimer

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

func NewSipTimer

func NewSipTimer(d, max time.Duration, f func()) *SipTimer

func (*SipTimer) Reset

func (t *SipTimer) Reset(d time.Duration)

type State

type State int

状态机之状态

const (
	/* STATES for invite client transaction */
	ICT_PRE_CALLING State = iota
	ICT_CALLING
	ICT_PROCEEDING
	ICT_COMPLETED
	ICT_TERMINATED

	/* STATES for invite server transaction */
	IST_PRE_PROCEEDING
	IST_PROCEEDING
	IST_COMPLETED
	IST_CONFIRMED
	IST_TERMINATED

	/* STATES for NON-invite client transaction */
	NICT_PRE_TRYING
	NICT_TRYING
	NICT_PROCEEDING
	NICT_COMPLETED
	NICT_TERMINATED

	/* STATES for NON-invite server transaction */
	NIST_PRE_TRYING
	NIST_TRYING
	NIST_PROCEEDING
	NIST_COMPLETED
	NIST_TERMINATED

	/* STATES for dialog */
	DIALOG_EARLY
	DIALOG_CONFIRMED
	DIALOG_CLOSE
)

func (State) String

func (s State) String() string

type Transaction

type Transaction struct {
	context.Context //线程管理、其他参数
	sync.Mutex
	// contains filtered or unexported fields
}

是否需要tp layer?

func (*Transaction) GetTid

func (ta *Transaction) GetTid() string

func (*Transaction) Run

func (ta *Transaction) Run(evt Event, m *sip.Message)

每一个transaction至少有一个状态机线程运行 TODO:如果是一个uac的transaction,则把最后响应的消息返回(通过response chan) transaction有很多消息需要传递到TU,也接收来自TU的消息。

func (*Transaction) RunAfter

func (ta *Transaction) RunAfter(t time.Duration, evt Event)

func (*Transaction) SetState

func (ta *Transaction) SetState(s State)

func (*Transaction) SipSend

func (ta *Transaction) SipSend(msg *sip.Message) error

根据sip消息,解析出目标服务器地址,发送消息

func (*Transaction) Terminate

func (ta *Transaction) Terminate()

Terminated:事物的终止 TODO:check调用时机

Jump to

Keyboard shortcuts

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