Sun GlassFish Communications Server 2.0 版本說明

SIP 階段作業和 HTTP 階段作業沒有套用相同的階段作業過期時間模型 (問題 1180)

說明

SIP 階段作業的階段作業過期模型和 HTTP 過期時間邏輯不同。在 HTTP 方面,每當在 HTTP 階段作業中接收到新的 HTTP 請求時,該階段作業會自動延伸,並不會受到應用程式的控制。

而在 SIP 階段作業方面,應用程式會在 SIP 容器的許可下,控制 SipApplicationSession (SAS) 的持續時間。應用程式可以使用 setExpires 方法指出 SAS 何時應過期。setExpires 會相對於呼叫 setExpires 方法的時間來定義過期時間。容器可以修改、拒絕或接受 setExpires 中所指出的持續時間。如果階段作業沒有失效,則會在 setExpires 定義的時間執行 sessionExpired 回呼。在此回呼中,應用程式可以嘗試呼叫新的 setExpires 以延伸 SAS 的持續時間,但仍會受到容器的修改、拒絕或接受控制。

因此,使用與 SipApplicationSession (SAS) 相同的過期時間啟動且位於 HTTP 階段作業的整合應用程式,在 HTTP 階段作業中接收到新的請求時,會發現 SAS 在 HTTP 階段作業前逾時。

解決方案

對於 SIP 和 HTTP 階段作業兩者不同的過期時間處理,最好的應付方式是啟動階段作業時使用夠長的 SAS 過期時間,此一過期時間即為應用程式階段作業預期存在 (包括數個 HTTP 請求) 的總時間長度。SAS 使用期限甚至可以設為無限,特別是使用 invalidateWhenReady 語義時,在這個情況下,SipApplicationSession 會在最後的協定子階段作業失效時失效。SAS 的初始過期時間可以在部署描述元中配置。

如果可以事先估計最大總持續時間,就不需要額外的程式碼,因為在 SAS 過期時讓 Sip 階段作業和 HTTP 階段作業失效非常適當。如果無法事先估計最大持續時間,則 SipApplicationSession 可以在其過期後延伸,如以下程式碼片段內容所示。

SipApplicationSessionListener 實作中,您可以進行類似這樣的作業:

public void sessionExpired(SipApplicationSessionEvent sasEvent) {
                // check if the SAS needs to be extended first, if so:
		int granted = sasEvent.getApplicationSession().setExpires(2);
		if (granted <= 0) {
			System.out.println("extension rejected");
		} else if (granted < 2) {
			System.out.println("extension granted with lower value " + granted);
		} // else allowed 
	}