Sun GlassFish Communications Server 2.0 发行说明

SIP 容器

SIP 容器在发送 100 响应后无法处理 CANCEL(问题 712)

说明

在发送 100 响应之后,SIP 容器无法处理 CANCEL 请求。

解决方法

应用程序需要发送一个临时响应(如 1xx),以便远程端可以取消该 INVITE 请求。

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 
	}

容器回调 sessionExpired 时 SIP 会话依旧存活(问题 1265)

说明

这是间歇性的问题。在 200 NOTIFY(指示会话已删除)与客户端在收到该 NOTIFY 时发送的 SUBSCRIBE 之间存在竞争条件时,SIP 容器间歇性地响应“500 服务器内部错误”消息,而不是“481 调用/事务不存在”消息。

解决方法

客户端需要在订阅到期之前早早刷新 SUBSCRIBE。

Communications Server 先扮演 UAS 角色,接着是代理角色,然后生成 NOP(问题 1432)

说明

在收到 INVITE 请求时,Communications Server 先扮演 UAS 角色,以 1XX 回复该请求,然后将此 INVITE 请求代理至另一实例,而该实例回复 200 OK。1xx 创建内部虚拟分支,而 200 消息则创建实际分支。从 B 收到 200 OK 时,内部虚拟分支应会取消。

解决方法

此异常跟踪不会影响虚拟代理分支的功能。

getLastAccessedTime 方法不能提供准确的结果(问题 1351)

说明

SIP 会话的 getLastAccessedTime 方法不能提供准确的结果。

解决方法

需要准确跟踪 lastAccessedTime 的应用程序必须自行将其存储到 SipApplicationSession 中。

synchronized (sas) {
	Long last = (Long) sas.getAttribute("myLastAccessedTime");
	if (last == null) {last = 0};
	// do something with the last one
	// and...
	// set the new one.
	sas.setAttribute("myLastAccessedTime", System.currentTimeMillis());
}

SIP 侦听器在删除后还能在一段时间内保持活动状态(问题 1294)

说明

为 TCP 和 UDP 请求配置的 SIP 侦听器在删除后,还能在一段时间内保持活动状态。发送至该侦听器的 UDP 请求会收到其响应。

解决方法

没有已知的解决方法。该 SIP 侦听器会在一段时间后停止侦听 UDP 请求。此问题不影响 TCP 请求。

Communications Server 在收到不带“<>”的连接头时抛出异常(问题 1489)

说明

Communications Server 在收到不带“<>”的连接头时抛出异常。根据 SIP RFC 3261,地址中不强制使用“<>”。这会引起与其他符合 SIP 的设备的互操作性问题。

解决方法

在连接头中使用“<>”。

Communications Server 在无效 UUID 值上抛出异常(问题 1494)

说明

Communications Server 在无效 UUID 值上抛出异常,而不是返回“400 错误的请求”。UUID 值驻留在 SIP 连接头的 sip.instance 值中。

解决方法

没有已知的解决方法。

Windows:Communications Server 有时收不到 UDP 消息(无编号)

说明

此问题仅会间歇性地在 Windows 上出现。Communications Server 收不到 UDP 消息。

解决方法

按以下方式设置如下 JVM 选项,再重新启动 Communications Server。

org.jvnet.glassfish.comms.disableUDPSourcePort=true