您當前的位置是:  首頁 > 資訊 > 文章精選 >
 首頁 > 資訊 > 文章精選 >

分叉呼叫(Fork) 具體處理流程分析

2019-04-08 14:27:55   作者: james.zhu   來源:CTI論壇   評論:0  點擊:


  在很多SIP呼叫應用中,我們經(jīng)常會遇到這樣的使用場景。當一端客戶對另外一端呼叫發(fā)起呼叫時,SIP服務器端按照系統(tǒng)的設置,可能同時對另外一端的辦公室桌面電話發(fā)起呼叫,也可能同時對你的手機app分機發(fā)起呼叫。類似于一個呼叫經(jīng)過代理服務器處理以后,進行了分叉處理(和叉子相似)
  還有一種可能就是服務器端同時對多臺不同的終端不同用戶進行呼叫。但是,如果有多臺終端被同時呼叫時,代理服務器如何才能知道哪臺是終端第一個應答的呼叫,如何處理那些沒有應答呼叫的終端或者稍晚應答的呼叫的終端。為了回答這個問題,我們需要詳細地分析關鍵參數(shù)-branch為大家進行比較詳細地剖析。
  1、Forking呼叫背景知識
  在前面的很多文章中筆者已經(jīng)討論過Forking 呼叫的具體流程,為了讓讀者能夠快速了解Forking呼叫,我們再次做一個簡單的回顧。Forking呼叫事實上是相對于并行按序呼叫來說的。一端發(fā)起呼叫后,通過SIP服務器端可以同時對多臺終端進行呼叫,首先接聽的開始通話。其他終端呼叫則被取消。
  在具體的應用環(huán)境中,用戶可以發(fā)起一個呼叫振鈴組,或者分機隨行等功能。如何實現(xiàn)這個具體的功能,每個廠家的產(chǎn)品不同可能配置命令有所不同。在Asterisk中,可以通過以下語法來實現(xiàn)同時對三臺SIP分機進行呼叫。
  exten => s,1,Dial(SIP/s1&SIP/s2&SIP/s3,10)
  以上語法簡單來說,就是通知系統(tǒng)同時呼叫分機s1,s2,和s3。
  2、Branch定義和神奇的七個字符
  在進行具體的討論之前,我們這里需要介紹一下branch。在RFC3261中,branch是這樣定義的:
  The Via header field value MUST contain a branch parameter.  This parameter is used to identify the transaction created by that request.  This parameter is used by both  the client and the server.
  https://www.rfc-editor.org/rfc/rfc3261.txt
  通過以上規(guī)范,我們可以理解,branch是用來確認事務的,并且branch會被使用在終端和服務器端。另外,每個branch id必須是唯一的,以字符串“z9hG4bK”開頭。在RFC3261規(guī)范說明中,僅簡單說明使用這7個神奇的字符這是為了防止和rfc2453的規(guī)范沖突,rfc2453不使用這個值。為了進一步了解為什么使用這七個字符,筆者也查閱了很多文章和論文,沒有看到為什么使用這七個神奇字符的具體的原因。
  3、Fork初始化
  根據(jù)我們上面介紹的關于分叉處理的機制,我們可以看到,一般來說,分叉呼叫大概的流程是這樣的。一個SIP終端發(fā)起呼叫,通過了SIP服務器以后,分別對兩個終端進行了呼叫,并且分別進行分叉處理,F(xiàn)在的問題是,如果第一個分機首先應答了這個呼叫后,服務器端怎么才能知道哪個終端執(zhí)行了應答。
  為了解決這個問題,我們需要借助branch id來處理。具體的語法格式如下:
  Via:SIP/2.0/UDP erlang.bell-telephone.com:5060;branch=z9hG4bK87asdks7 Via: SIP/2.0/UDP 192.0.2.1:5060 ;received=192.0.2.207 ;branch=z9hG4bK77asjd
  https://www.rfc-editor.org/rfc/rfc3261.txt
  4、在呼叫時插入branch id
  SIP服務器端在對其他分機進行呼叫時,分別添加了自己的branch id號(這里簡化表達),并且生成了一個專門對每一個終端的branch id。這樣就確認了終端和服務器端的關系。
  當?shù)谝粋SIP分機首先接聽時,服務器端收到200 OK,服務器端會根據(jù)branch id來確定是第一個分機的應答。應答以后,雙方開始其他的流程處理。
  5、取消其他沒有接通的呼叫
  接通了雙方通話以后,接下來,SIP服務器端會根據(jù)branch判斷其他未接聽的終端,分別對其終端發(fā)送Cancel。
  這里,讀者需要注意,SIP 服務器發(fā)送到Cancel仍然使用的是同樣的branch id。如果是這樣的話,這里的處理是否和RFC3261的定義沖突?因為一般情況下,這個branch id是唯一的。答案顯然不是。在RFC3261中還有這樣的一個規(guī)定:
  The branch parameter value MUST be unique across space and time for all requests sent by the UA.  The exceptions to this rule are CANCEL and ACK for  non-2xx responses.  As discussed below, a CANCEL request  will have the same value of the branch parameter as the request it  cancels.
  https://www.rfc-editor.org/rfc/rfc3261.txt
  因此,在Cancel請求發(fā)送時,仍然可以使用原來同樣的branch id,否則SIP服務器端沒有辦法根據(jù)其唯一性來取消其他服務。
  6、總結(jié)
  通過以上介紹,筆者可能基本了解了如何處理分叉呼叫的機制。其過程主要借助了branch id的方式來確認每個分支的身份確認信息。服務器端在Via頭中增加一個branch id來識別其處理身份。在遠端用戶應答率呼叫后,服務器端可以通過ID來識別其終端,然后轉(zhuǎn)發(fā)會呼叫方進行下一步處理。如果沒有在第一時間應答的用戶則會根據(jù)id發(fā)送Cancel請求。
  以上過程就是一個簡單的分叉呼叫的流程,另外,筆者提醒讀者,需要特別注意到還有一個branch id的七個神奇字符的問題,筆者沒有看到比較權威的解釋。在處理Cancel時,用戶一定要注意,Cancel需要使用同一branch id,而不是再使用新的唯一的id。
  參考資料:
  https://andrewjprokop.wordpress.com/2015/04/07/multiple-registration-and-call-forking-with-sip/
  https://tools.ietf.org/html/rfc3261#section-8.1.1.7
  https://mailarchive.ietf.org/arch/msg/sip/_5zV4Vh41XqgTBYfpzZP19fLpOM
【免責聲明】本文僅代表作者本人觀點,與CTI論壇無關。CTI論壇對文中陳述、觀點判斷保持中立,不對所包含內(nèi)容的準確性、可靠性或完整性提供任何明示或暗示的保證。請讀者僅作參考,并請自行承擔全部責任。

專題

CTI論壇會員企業(yè)