9 Canceling a Request
在前面的章節(jié)中,我們已經(jīng)討論了關(guān)于標(biāo)準(zhǔn)UA的處理流程,包括method的請(qǐng)求所產(chǎn)生的請(qǐng)求和處理響應(yīng)流程。在這個(gè)章節(jié),我們討論CANCEL,它是一個(gè)目的性比較強(qiáng)的method。
CANCEL請(qǐng)求和它的名字一樣,它是用來(lái)取消前面由客戶端發(fā)送的請(qǐng)求。具體來(lái)說(shuō),它要求UAS退出前面的請(qǐng)求,并且針對(duì)那個(gè)請(qǐng)求生成一個(gè)錯(cuò)誤響應(yīng)。如果UAS已經(jīng)針對(duì)一個(gè)請(qǐng)求生成了最終響應(yīng)回復(fù),這時(shí),CANCEL再次針對(duì)這個(gè)請(qǐng)求發(fā)送取消的話是無(wú)效的。因?yàn)檫@個(gè)原因,大部分的CANCEL請(qǐng)求都需要服務(wù)器端耗費(fèi)比較長(zhǎng)的時(shí)間做出響應(yīng)回復(fù)。因此,對(duì)于INVITE來(lái)說(shuō),使用CANCEL是最好的辦法,這樣就可以通過(guò)一個(gè)比較長(zhǎng)的時(shí)間生成響應(yīng)回復(fù)。 在以上使用環(huán)境中,接收CANCEL請(qǐng)求的UAS,在還沒(méi)有發(fā)送最終響應(yīng)時(shí),UAS將會(huì)處理一個(gè)“stop ringing”,然后再針對(duì)這個(gè)INVITE發(fā)送一個(gè)特別錯(cuò)誤響應(yīng)碼(一個(gè)487)。
代理服務(wù)器和用戶代理客戶端都可以創(chuàng)建和發(fā)送CANCEL響應(yīng)。Section 15 討論了UAC取消INVITE請(qǐng)求的條件,Section 16.10 討論了代理使用CANCEL的細(xì)節(jié)。
有狀態(tài)代理響應(yīng)一個(gè)CANCEL請(qǐng)求,而不是簡(jiǎn)單前轉(zhuǎn)一個(gè)從下游要素中收到的響應(yīng)。因?yàn)槟莻(gè)原因,CANCEL被看作是一個(gè)“hop-by-hop”請(qǐng)求,因?yàn)樗换貜?fù)是在每個(gè)有狀態(tài)代理hop的節(jié)點(diǎn)上的。
9.1 Client Behavior
一個(gè)CANCEL請(qǐng)求只能用來(lái)取消一個(gè)INVITE請(qǐng)求,不應(yīng)該發(fā)送去取消其他的請(qǐng)求。
因?yàn)槌薎NVITE請(qǐng)求以外,其他請(qǐng)求會(huì)馬上響應(yīng)這個(gè)請(qǐng)求,因此,發(fā)送一個(gè)CANCEL請(qǐng)求到一個(gè)非INVITE請(qǐng)求總會(huì)創(chuàng)建一個(gè)互相競(jìng)爭(zhēng)的條件。
以下流程用來(lái)構(gòu)建一個(gè)CANCEL請(qǐng)求。在CANCEL請(qǐng)求中的Request-URI,Call-ID, To,CSeq的數(shù)字部分,和From頭域值必須是確認(rèn)的,這些參數(shù),包括標(biāo)簽是在被取消的請(qǐng)求中。通過(guò)客戶端構(gòu)建的CANCEL中必須只有一個(gè)Via頭值匹配被取消的請(qǐng)求中的最頂部的Via頭域值。使用這些頭域中同樣的值允許此CANCEL匹配它將要取消的請(qǐng)求。(Section 9.2 說(shuō)明了匹配是如何發(fā)生的)。但是,此CSeq頭域中的method部分必須含有一個(gè)CANCEL的值。通過(guò)這樣的處理流程,作為一個(gè)事務(wù),在它的具有權(quán)限范圍內(nèi),CANCEL才可以被完整確認(rèn)和處理。 (參考 Section 17)。
如果這個(gè)被正在取消的請(qǐng)求中包含了一個(gè)Route頭域值,此CANCEL請(qǐng)求必須包括那個(gè) Route頭域的值。
這個(gè)要求是一個(gè)必須條件,通過(guò)這樣的處理要求,無(wú)狀態(tài)代理才能正確地路由此CANCEL請(qǐng)求。
CANCEL請(qǐng)求中一定不能包含任何Require或Proxy-Require頭。
一旦CANCEL被創(chuàng)建以后,客戶端應(yīng)該檢查針對(duì)正在被取消的請(qǐng)求,它這里是否收到任何響應(yīng)消息(臨時(shí)響應(yīng)或最終響應(yīng))(因此,這里的請(qǐng)求是一個(gè)原始請(qǐng)求)。
如果客戶端沒(méi)有收到任何臨時(shí)響應(yīng),CANCEL一定不能被發(fā)送;相反,客戶端必須在發(fā)送請(qǐng)求之前等待臨時(shí)響應(yīng)到達(dá)。如果初始的請(qǐng)求已經(jīng)生成了一個(gè)最終響應(yīng),這個(gè)請(qǐng)求就不應(yīng)該被發(fā)送出去了,這是一個(gè)無(wú)效操作,因?yàn)檫@個(gè)CANCEL請(qǐng)求已經(jīng)對(duì)這個(gè)初始請(qǐng)求沒(méi)有任何作用,這個(gè)請(qǐng)求已經(jīng)生成了最終響應(yīng)。當(dāng)客戶端決定發(fā)送CANCEL時(shí),它針對(duì)這個(gè)CANCEL創(chuàng)建一個(gè)客戶端事務(wù),然后傳輸這個(gè)事務(wù),包括這個(gè)CANCEL請(qǐng)求關(guān)聯(lián)的目的地地址,端口和傳輸方式內(nèi)容。針對(duì)這個(gè)CANCEL請(qǐng)求定義的目的地地址,端口和傳輸方式必須和發(fā)送初始請(qǐng)求的互相確認(rèn)。
在接收前一個(gè)請(qǐng)求的響應(yīng)之前,如果被允許發(fā)送CANCEL,在初始請(qǐng)求之前,服務(wù)器 可以接收這個(gè)CANCEL。
注意,兩種事務(wù)-相對(duì)于初始請(qǐng)求的事務(wù)和CANCEL事務(wù),它們都是獨(dú)立完成的。但是,一個(gè)正在處理取消請(qǐng)求的UAC不能依賴于針對(duì)初始請(qǐng)求的響應(yīng)-487(請(qǐng)求結(jié)束),因?yàn)樾枰3趾蚏FC 2543的一致性,UAS將不會(huì)生成一個(gè)這樣的響應(yīng)。如果在64*T1秒內(nèi),針對(duì)初始請(qǐng)求沒(méi)有收到最終響應(yīng)的話,
這個(gè)客戶端應(yīng)該可以認(rèn)為這個(gè)初始事務(wù)可以被取消,并且應(yīng)該銷毀這個(gè)正在負(fù)責(zé)初始請(qǐng)求的客戶端事務(wù)。
9.2 Server Behavior
CANCEL method要求在服務(wù)器端的事務(wù)用戶(TU)取消待處理的事務(wù)。TU通過(guò)執(zhí)行CANCEL請(qǐng)求決定事務(wù)是否取消,而且假設(shè)請(qǐng)求method是任何一種method,但是 CANCEL或者ACK可以應(yīng)用事務(wù)匹配流程,具體匹配流程在Section 17.2.3有所討論。這個(gè)匹配的事務(wù)是其中一個(gè)將被取消的事務(wù)。
在服務(wù)器端關(guān)于執(zhí)行CANCEL請(qǐng)求的流程完全取決于服務(wù)器類型。一個(gè)無(wú)狀態(tài)代理會(huì)前轉(zhuǎn)這個(gè)取消請(qǐng)求,一個(gè)有狀態(tài)代理可能會(huì)有響應(yīng)消息,生成它自己的一些CANCEL請(qǐng)求,然后UAS回復(fù)這些響應(yīng)。查閱Section 16.10 獲得關(guān)于CANCEL的代理處理方式。
根據(jù)標(biāo)準(zhǔn)UAS的處理方式,UAS首先處理CANCEL請(qǐng)求,具體的處理方式描述在Section 8.2有更多介紹。但是,因?yàn)镃ANCEL請(qǐng)求是hop-by-hop的處理方式,因此它不能被重新提交。服務(wù)器端也不會(huì)驗(yàn)證其在Authorization頭中獲得安全驗(yàn)證消息。注意,CANCEL 請(qǐng)求也不包含Require頭域。
根據(jù)以上所說(shuō)的處理流程,如果UAS沒(méi)有發(fā)現(xiàn)一個(gè)針對(duì)CANCEL的匹配事務(wù)的話,它應(yīng)該對(duì)這個(gè)CANCEL響應(yīng)一個(gè)481錯(cuò)誤碼(Call Leg/Transaction Does Not Exist)。如果關(guān)聯(lián)初始請(qǐng)求的事務(wù)仍然存在的話,收到CANCEL請(qǐng)求的UAC的執(zhí)行方式取決于這個(gè)UAC是否已經(jīng)針對(duì)關(guān)聯(lián)的初始請(qǐng)求已經(jīng)發(fā)送了最終響應(yīng)。如果已經(jīng)發(fā)送了最終響應(yīng),那么這個(gè)CANCEL請(qǐng)求對(duì)初始請(qǐng)求處理沒(méi)有任何影響,對(duì)任何會(huì)話狀態(tài)沒(méi)有任何影響,對(duì)初始請(qǐng)求生成的響應(yīng)沒(méi)有任何影響。如果這個(gè)UAS沒(méi)有發(fā)送最終響應(yīng)的話,這個(gè)UAS的處理流程則取決于初始請(qǐng)求的method。進(jìn)一步說(shuō),如果初始請(qǐng)求是一個(gè)INVITE method,這個(gè)UAS應(yīng)該對(duì)這個(gè)INVITE馬上回復(fù)一個(gè)487錯(cuò)誤碼(Request Terminated)。CANCEL請(qǐng)求不會(huì)對(duì)本規(guī)范中所定義的其他method所產(chǎn)生的事務(wù)有影響,僅對(duì)自己的method所產(chǎn)生的事務(wù)有影響。
無(wú)論初始請(qǐng)求的method是何種method,只要CANCEL匹配了一個(gè)現(xiàn)存的事務(wù),這個(gè)UAS應(yīng)該自己應(yīng)答這個(gè)CANCEL,并且返回一個(gè)200(OK)響應(yīng)。這個(gè)響應(yīng)消息是通過(guò)以下處理流程來(lái)創(chuàng)建的,具體創(chuàng)建流程查閱Section 8.2.6,這里需要注意,對(duì)于CANCEL來(lái)說(shuō),這個(gè)響應(yīng)中的這個(gè)To標(biāo)簽和初始請(qǐng)求中的響應(yīng)中的To標(biāo)簽應(yīng)該相同。這個(gè)CANCEL的回復(fù)響應(yīng)被傳遞到這個(gè)服務(wù)器的事務(wù)處理進(jìn)行傳輸。
繼續(xù)發(fā)布……
關(guān)注微信公眾號(hào):asterisk-cn,獲得有價(jià)值的Asterisk行業(yè)分享
Asterisk freepbx,F(xiàn)reeSBC技術(shù)文檔:www.freepbx.org.cn
融合通信商業(yè)解決方案,協(xié)同解決方案首選產(chǎn)品:www.hiastar.com
Asterisk / FreePBX / FreeSBC中國(guó)合作伙伴,官方qq技術(shù)分享群(3000人):589995817